commit 6b3360bdbb66f0dd15274a0ac9de0415f5243c42 parent ad4e00f14c67471718e168a8d586223591fa53b8 Author: t3sserakt <t3ss@posteo.de> Date: Sat, 10 Aug 2024 09:52:33 +0200 Added monolith variant. Diffstat:
101 files changed, 40148 insertions(+), 53 deletions(-)
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 = 34 + compileSdk = 35 defaultConfig { applicationId = "org.gnu.gnunet" minSdk = 31 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" diff --git a/android_studio/app/src/main/cpp/CMakeLists.txt b/android_studio/app/src/main/cpp/CMakeLists.txt @@ -14,36 +14,21 @@ 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(sqliteX SHARED IMPORTED) set_target_properties(sqliteX PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/sqlite/lib/${ANDROID_ABI}/libsqliteX.so) -add_library(libgnunetstatistics SHARED IMPORTED) -set_target_properties(libgnunetstatistics PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunetstatistics/lib/${ANDROID_ABI}/libgnunetstatistics.so) -add_library(libgnunettransportcore SHARED IMPORTED) -set_target_properties(libgnunettransportcore PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunettransportcore/lib/${ANDROID_ABI}/libgnunettransportcore.so) -add_library(libgnunettransportcommunicator SHARED IMPORTED) -set_target_properties(libgnunettransportcommunicator PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunettransportcommunicator/lib/${ANDROID_ABI}/libgnunettransportcommunicator.so) -add_library(libgnunettransportapplication SHARED IMPORTED) -set_target_properties(libgnunettransportapplication PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunettransportapplication/lib/${ANDROID_ABI}/libgnunettransportapplication.so) -add_library(libgnunettransportmonitor SHARED IMPORTED) -set_target_properties(libgnunettransportmonitor PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunettransportmonitor/lib/${ANDROID_ABI}/libgnunettransportmonitor.so) -add_library(libgnunetpeerstore SHARED IMPORTED) -set_target_properties(libgnunetpeerstore PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunetpeerstore/lib/${ANDROID_ABI}/libgnunetpeerstore.so) -add_library(libgnunetarm SHARED IMPORTED) -set_target_properties(libgnunetarm PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunetarm/lib/${ANDROID_ABI}/libgnunetarm.so) +add_library(libgnunetutil SHARED IMPORTED) +set_target_properties(libgnunetutil PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/libgnunetutil/lib/${ANDROID_ABI}/libgnunetutil.so) add_library(libgnunethello SHARED IMPORTED) set_target_properties(libgnunethello PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/libgnunethello/lib/${ANDROID_ABI}/libgnunethello.so) -add_library(libgnunetsq SHARED IMPORTED) -set_target_properties(libgnunetsq PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunetsq/lib/${ANDROID_ABI}/libgnunetsq.so) +add_library(libgnunet SHARED IMPORTED) +set_target_properties(libgnunet PROPERTIES IMPORTED_LOCATION + ${distribution_DIR}/libgnunet/lib/${ANDROID_ABI}/libgnunet.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) @@ -74,9 +59,6 @@ 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(libgnunetutil SHARED IMPORTED) -set_target_properties(libgnunetutil PROPERTIES IMPORTED_LOCATION - ${distribution_DIR}/libgnunetutil/lib/${ANDROID_ABI}/libgnunetutil.so) # build application's shared lib set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") @@ -100,6 +82,7 @@ add_library(gnunet SHARED ) target_include_directories(gnunet PRIVATE + ${distribution_DIR}/libidn/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 @@ -112,15 +95,8 @@ target_include_directories(gnunet PRIVATE ${distribution_DIR}/libintl/lib/${ANDROID_ABI}/include ${distribution_DIR}/gettext/lib/${ANDROID_ABI}/include ${distribution_DIR}/libgnunetutil/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunetstatistics/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunettransportcore/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunettransportcommunicator/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunettransportapplication/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunettransportmonitor/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunetpeerstore/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunetarm/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunethello/lib/${ANDROID_ABI}/include - ${distribution_DIR}/libgnunetsq/lib/${ANDROID_ABI}/include) + ${distribution_DIR}/libgnunet/lib/${ANDROID_ABI}/include + ${distribution_DIR}/libgnunethello/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 @@ -132,6 +108,7 @@ target_link_libraries(gnunet libgcrypt libsodium libtool + libidn gmp libunistring libz @@ -139,16 +116,9 @@ target_link_libraries(gnunet libintl libgettext libgnunetutil - sqliteX - libgnunetstatistics - libgnunettransportcore - libgnunettransportcommunicator - libgnunettransportapplication - libgnunettransportmonitor - libgnunetpeerstore - libgnunetarm libgnunethello - libgnunetsq + libgnunet + sqliteX log) target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384") \ 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 @@ -17,7 +17,43 @@ extern "C" { #include <gnunet_util_lib.h> } -/** Milestone 6-7 code. +static int pfd[2]; +static pthread_t thr; +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); + } + return 0; +} + +int start_logger(const char *app_name) +{ + tag = app_name; + + /* make stdout line-buffered and stderr unbuffered */ + setvbuf(stdout, 0, _IOLBF, 0); + setvbuf(stderr, 0, _IONBF, 0); + + /* create the pipe and redirect stdout and stderr */ + pipe(pfd); + dup2(pfd[1], 1); + dup2(pfd[1], 2); + + /* spawn the logging thread */ + if(pthread_create(&thr, 0, thread_func, 0) == -1) + return -1; + pthread_detach(thr); + return 0; +} + +/** ------------------ Milestone 6-7 code. ------------------------------- static void run (void *cls, char *const *args, @@ -78,6 +114,8 @@ shutdown: GNUNET_SCHEDULER_shutdown(); }*/ +// END ------------------------------ Milestone 6 - 7 Code --------------------- + static jobject android_java_asset_manager = NULL; static struct GNUNET_ARM_Handle *h; static struct GNUNET_CONFIGURATION_Handle *cfg; @@ -153,6 +191,7 @@ conn_status (void *cls, once = 1; } +/* -------------- Multi library code ----------------------------- static void run (void *cls, @@ -160,6 +199,10 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { + start_logger(tag); + printf("Some message.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Simulate error message. We do not no what is the actual log level.\n"); cfg = GNUNET_CONFIGURATION_dup (c); AAssetManager *mgr = static_cast<AAssetManager *>(cls); AAsset *asset = AAssetManager_open(mgr, "gnunet.conf", AASSET_MODE_BUFFER); @@ -174,6 +217,7 @@ run (void *cls, AAsset_close(asset); + if (NULL == (h = GNUNET_ARM_connect (cfg, &conn_status, NULL))) @@ -185,8 +229,9 @@ run (void *cls, &start_callback, NULL); -} +} + END -------------- Multi library code ----------------------------- */ extern "C" JNIEXPORT jstring JNICALL Java_org_gnu_gnunet_MainActivity_stringFromJNI( @@ -199,8 +244,10 @@ Java_org_gnu_gnunet_MainActivity_stringFromJNI( AAssetManager *mgr = AAssetManager_fromJava(env, android_java_asset_manager); char *const argvx[] = { - "server", - "8081", + "-L", + "DEBUG", + "-l", + "test.out", NULL }; @@ -211,13 +258,35 @@ Java_org_gnu_gnunet_MainActivity_stringFromJNI( std::string tmp_file = GNUNET_DISK_mktemp ("test"); LOGD ("Temp file is here: %s", tmp_file.c_str()); - GNUNET_PROGRAM_run (1, + + start_logger(tag); + printf("Some message.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Simulate error message. We do not no what is the actual log level.\n"); + cfg = GNUNET_CONFIGURATION_create (); + AAsset *asset = AAssetManager_open(mgr, "gnunet.conf", AASSET_MODE_BUFFER);Are ther + char buf[AAsset_getLength(asset)]; + + AAsset_read(asset, buf, AAsset_getLength(asset)); + + if (GNUNET_OK != GNUNET_CONFIGURATION_deserialize (cfg, buf, strlen(buf), NULL)) + { + LOGE ("Deserialization of configuration failed!"); + } + + AAsset_close(asset); + + GNUNET_SERVICE_main (4, + argvx, + cfg); + + /*GNUNET_PROGRAM_run (4, argvx, "native-lib", "native-lib", options, &run, - mgr); + mgr);*/ std::string hello = "Hello from C++. Temp file is here: " + tmp_file; return env->NewStringUTF(hello.c_str()); 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 @@ -28,6 +28,7 @@ class MainActivity : AppCompatActivity() { companion object { // Used to load the 'gnunet' library on application startup. init { + System.loadLibrary("sqliteX"); System.loadLibrary("gnunet") } } diff --git a/android_studio/app/src/main/java/org/sqlite/database/DatabaseErrorHandler.java b/android_studio/app/src/main/java/org/sqlite/database/DatabaseErrorHandler.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + + +package org.sqlite.database; + +import org.sqlite.database.sqlite.SQLiteDatabase; + +/** + * An interface to let apps define an action to take when database corruption is detected. + */ +public interface DatabaseErrorHandler { + + /** + * The method invoked when database corruption is detected. + * @param dbObj the {@link SQLiteDatabase} object representing the database on which corruption + * is detected. + */ + void onCorruption(SQLiteDatabase dbObj); +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/DatabaseUtils.java b/android_studio/app/src/main/java/org/sqlite/database/DatabaseUtils.java @@ -0,0 +1,1461 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sqlite.database; + +import android.content.ContentValues; +import android.content.Context; +import android.content.OperationApplicationException; +import org.sqlite.database.sqlite.SQLiteAbortException; +import org.sqlite.database.sqlite.SQLiteConstraintException; +import org.sqlite.database.sqlite.SQLiteDatabase; +import org.sqlite.database.sqlite.SQLiteDatabaseCorruptException; +import org.sqlite.database.sqlite.SQLiteDiskIOException; +import org.sqlite.database.sqlite.SQLiteException; +import org.sqlite.database.sqlite.SQLiteFullException; +import org.sqlite.database.sqlite.SQLiteProgram; +import org.sqlite.database.sqlite.SQLiteStatement; + +import android.database.CursorWindow; +import android.os.OperationCanceledException; +import android.os.Parcel; +import android.os.ParcelFileDescriptor; +import android.text.TextUtils; +import android.util.Log; + +import android.database.Cursor; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintStream; +import java.text.Collator; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * Static utility methods for dealing with databases and {@link Cursor}s. + */ +public class DatabaseUtils { + private static final String TAG = "DatabaseUtils"; + + private static final boolean DEBUG = false; + + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_SELECT = 1; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_UPDATE = 2; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_ATTACH = 3; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_BEGIN = 4; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_COMMIT = 5; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_ABORT = 6; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_PRAGMA = 7; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_DDL = 8; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_UNPREPARED = 9; + /** One of the values returned by {@link #getSqlStatementType(String)}. */ + public static final int STATEMENT_OTHER = 99; + + /** + * Special function for writing an exception result at the header of + * a parcel, to be used when returning an exception from a transaction. + * exception will be re-thrown by the function in another process + * @param reply Parcel to write to + * @param e The Exception to be written. + * @see Parcel#writeNoException + * @see Parcel#writeException + */ + public static final void writeExceptionToParcel(Parcel reply, Exception e) { + int code = 0; + boolean logException = true; + if (e instanceof FileNotFoundException) { + code = 1; + logException = false; + } else if (e instanceof IllegalArgumentException) { + code = 2; + } else if (e instanceof UnsupportedOperationException) { + code = 3; + } else if (e instanceof SQLiteAbortException) { + code = 4; + } else if (e instanceof SQLiteConstraintException) { + code = 5; + } else if (e instanceof SQLiteDatabaseCorruptException) { + code = 6; + } else if (e instanceof SQLiteFullException) { + code = 7; + } else if (e instanceof SQLiteDiskIOException) { + code = 8; + } else if (e instanceof SQLiteException) { + code = 9; + } else if (e instanceof OperationApplicationException) { + code = 10; + } else if (e instanceof OperationCanceledException) { + code = 11; + logException = false; + } else { + reply.writeException(e); + Log.e(TAG, "Writing exception to parcel", e); + return; + } + reply.writeInt(code); + reply.writeString(e.getMessage()); + + if (logException) { + Log.e(TAG, "Writing exception to parcel", e); + } + } + + /** + * Special function for reading an exception result from the header of + * a parcel, to be used after receiving the result of a transaction. This + * will throw the exception for you if it had been written to the Parcel, + * otherwise return and let you read the normal result data from the Parcel. + * @param reply Parcel to read from + * @see Parcel#writeNoException + * @see Parcel#readException + */ +// public static final void readExceptionFromParcel(Parcel reply) { +// int code = reply.readExceptionCode(); +// if (code == 0) return; +// String msg = reply.readString(); +// DatabaseUtils.readExceptionFromParcel(reply, msg, code); +// } +// +// public static void readExceptionWithFileNotFoundExceptionFromParcel( +// Parcel reply) throws FileNotFoundException { +// int code = reply.readExceptionCode(); +// if (code == 0) return; +// String msg = reply.readString(); +// if (code == 1) { +// throw new FileNotFoundException(msg); +// } else { +// DatabaseUtils.readExceptionFromParcel(reply, msg, code); +// } +// } +// +// public static void readExceptionWithOperationApplicationExceptionFromParcel( +// Parcel reply) throws OperationApplicationException { +// int code = reply.readExceptionCode(); +// if (code == 0) return; +// String msg = reply.readString(); +// if (code == 10) { +// throw new OperationApplicationException(msg); +// } else { +// DatabaseUtils.readExceptionFromParcel(reply, msg, code); +// } +// } + + private static final void readExceptionFromParcel(Parcel reply, String msg, int code) { + switch (code) { + case 2: + throw new IllegalArgumentException(msg); + case 3: + throw new UnsupportedOperationException(msg); + case 4: + throw new SQLiteAbortException(msg); + case 5: + throw new SQLiteConstraintException(msg); + case 6: + throw new SQLiteDatabaseCorruptException(msg); + case 7: + throw new SQLiteFullException(msg); + case 8: + throw new SQLiteDiskIOException(msg); + case 9: + throw new SQLiteException(msg); + case 11: + throw new OperationCanceledException(msg); + default: + reply.readException(code, msg); + } + } + + /** + * Binds the given Object to the given SQLiteProgram using the proper + * typing. For example, bind numbers as longs/doubles, and everything else + * as a string by call toString() on it. + * + * @param prog the program to bind the object to + * @param index the 1-based index to bind at + * @param value the value to bind + */ + public static void bindObjectToProgram(SQLiteProgram prog, int index, + Object value) { + if (value == null) { + prog.bindNull(index); + } else if (value instanceof Double || value instanceof Float) { + prog.bindDouble(index, ((Number)value).doubleValue()); + } else if (value instanceof Number) { + prog.bindLong(index, ((Number)value).longValue()); + } else if (value instanceof Boolean) { + Boolean bool = (Boolean)value; + if (bool) { + prog.bindLong(index, 1); + } else { + prog.bindLong(index, 0); + } + } else if (value instanceof byte[]){ + prog.bindBlob(index, (byte[]) value); + } else { + prog.bindString(index, value.toString()); + } + } + + /** + * Returns data type of the given object's value. + *<p> + * Returned values are + * <ul> + * <li>{@link Cursor#FIELD_TYPE_NULL}</li> + * <li>{@link Cursor#FIELD_TYPE_INTEGER}</li> + * <li>{@link Cursor#FIELD_TYPE_FLOAT}</li> + * <li>{@link Cursor#FIELD_TYPE_STRING}</li> + * <li>{@link Cursor#FIELD_TYPE_BLOB}</li> + *</ul> + *</p> + * + * @param obj the object whose value type is to be returned + * @return object value type + * @hide + */ + public static int getTypeOfObject(Object obj) { + if (obj == null) { + return Cursor.FIELD_TYPE_NULL; + } else if (obj instanceof byte[]) { + return Cursor.FIELD_TYPE_BLOB; + } else if (obj instanceof Float || obj instanceof Double) { + return Cursor.FIELD_TYPE_FLOAT; + } else if (obj instanceof Long || obj instanceof Integer + || obj instanceof Short || obj instanceof Byte) { + return Cursor.FIELD_TYPE_INTEGER; + } else { + return Cursor.FIELD_TYPE_STRING; + } + } + + /** + * Fills the specified cursor window by iterating over the contents of the cursor. + * The window is filled until the cursor is exhausted or the window runs out + * of space. + * + * The original position of the cursor is left unchanged by this operation. + * + * @param cursor The cursor that contains the data to put in the window. + * @param position The start position for filling the window. + * @param window The window to fill. + * @hide + */ + public static void cursorFillWindow(final Cursor cursor, + int position, final CursorWindow window) { + if (position < 0 || position >= cursor.getCount()) { + return; + } + final int oldPos = cursor.getPosition(); + final int numColumns = cursor.getColumnCount(); + window.clear(); + window.setStartPosition(position); + window.setNumColumns(numColumns); + if (cursor.moveToPosition(position)) { + rowloop: do { + if (!window.allocRow()) { + break; + } + for (int i = 0; i < numColumns; i++) { + final int type = cursor.getType(i); + final boolean success; + switch (type) { + case Cursor.FIELD_TYPE_NULL: + success = window.putNull(position, i); + break; + + case Cursor.FIELD_TYPE_INTEGER: + success = window.putLong(cursor.getLong(i), position, i); + break; + + case Cursor.FIELD_TYPE_FLOAT: + success = window.putDouble(cursor.getDouble(i), position, i); + break; + + case Cursor.FIELD_TYPE_BLOB: { + final byte[] value = cursor.getBlob(i); + success = value != null ? window.putBlob(value, position, i) + : window.putNull(position, i); + break; + } + + default: // assume value is convertible to String + case Cursor.FIELD_TYPE_STRING: { + final String value = cursor.getString(i); + success = value != null ? window.putString(value, position, i) + : window.putNull(position, i); + break; + } + } + if (!success) { + window.freeLastRow(); + break rowloop; + } + } + position += 1; + } while (cursor.moveToNext()); + } + cursor.moveToPosition(oldPos); + } + + /** + * Appends an SQL string to the given StringBuilder, including the opening + * and closing single quotes. Any single quotes internal to sqlString will + * be escaped. + * + * This method is deprecated because we want to encourage everyone + * to use the "?" binding form. However, when implementing a + * ContentProvider, one may want to add WHERE clauses that were + * not provided by the caller. Since "?" is a positional form, + * using it in this case could break the caller because the + * indexes would be shifted to accomodate the ContentProvider's + * internal bindings. In that case, it may be necessary to + * construct a WHERE clause manually. This method is useful for + * those cases. + * + * @param sb the StringBuilder that the SQL string will be appended to + * @param sqlString the raw string to be appended, which may contain single + * quotes + */ + public static void appendEscapedSQLString(StringBuilder sb, String sqlString) { + sb.append('\''); + if (sqlString.indexOf('\'') != -1) { + int length = sqlString.length(); + for (int i = 0; i < length; i++) { + char c = sqlString.charAt(i); + if (c == '\'') { + sb.append('\''); + } + sb.append(c); + } + } else + sb.append(sqlString); + sb.append('\''); + } + + /** + * SQL-escape a string. + */ + public static String sqlEscapeString(String value) { + StringBuilder escaper = new StringBuilder(); + + DatabaseUtils.appendEscapedSQLString(escaper, value); + + return escaper.toString(); + } + + /** + * Appends an Object to an SQL string with the proper escaping, etc. + */ + public static final void appendValueToSql(StringBuilder sql, Object value) { + if (value == null) { + sql.append("NULL"); + } else if (value instanceof Boolean) { + Boolean bool = (Boolean)value; + if (bool) { + sql.append('1'); + } else { + sql.append('0'); + } + } else { + appendEscapedSQLString(sql, value.toString()); + } + } + + /** + * Concatenates two SQL WHERE clauses, handling empty or null values. + */ + public static String concatenateWhere(String a, String b) { + if (TextUtils.isEmpty(a)) { + return b; + } + if (TextUtils.isEmpty(b)) { + return a; + } + + return "(" + a + ") AND (" + b + ")"; + } + + /** + * return the collation key + * @param name + * @return the collation key + */ + public static String getCollationKey(String name) { + byte [] arr = getCollationKeyInBytes(name); + try { + return new String(arr, 0, getKeyLen(arr), "ISO8859_1"); + } catch (Exception ex) { + return ""; + } + } + + /** + * return the collation key in hex format + * @param name + * @return the collation key in hex format + */ + public static String getHexCollationKey(String name) { + byte[] arr = getCollationKeyInBytes(name); + char[] keys = encodeHex(arr); + return new String(keys, 0, getKeyLen(arr) * 2); + } + + + /** + * Used building output as Hex + */ + private static final char[] DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + private static char[] encodeHex(byte[] input) { + int l = input.length; + char[] out = new char[l << 1]; + + // two characters form the hex value. + for (int i = 0, j = 0; i < l; i++) { + out[j++] = DIGITS[(0xF0 & input[i]) >>> 4 ]; + out[j++] = DIGITS[ 0x0F & input[i] ]; + } + + return out; + } + + private static int getKeyLen(byte[] arr) { + if (arr[arr.length - 1] != 0) { + return arr.length; + } else { + // remove zero "termination" + return arr.length-1; + } + } + + private static byte[] getCollationKeyInBytes(String name) { + if (mColl == null) { + mColl = Collator.getInstance(); + mColl.setStrength(Collator.PRIMARY); + } + return mColl.getCollationKey(name).toByteArray(); + } + + private static Collator mColl = null; + /** + * Prints the contents of a Cursor to System.out. The position is restored + * after printing. + * + * @param cursor the cursor to print + */ + public static void dumpCursor(Cursor cursor) { + dumpCursor(cursor, System.out); + } + + /** + * Prints the contents of a Cursor to a PrintSteam. The position is restored + * after printing. + * + * @param cursor the cursor to print + * @param stream the stream to print to + */ + public static void dumpCursor(Cursor cursor, PrintStream stream) { + stream.println(">>>>> Dumping cursor " + cursor); + if (cursor != null) { + int startPos = cursor.getPosition(); + + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + dumpCurrentRow(cursor, stream); + } + cursor.moveToPosition(startPos); + } + stream.println("<<<<<"); + } + + /** + * Prints the contents of a Cursor to a StringBuilder. The position + * is restored after printing. + * + * @param cursor the cursor to print + * @param sb the StringBuilder to print to + */ + public static void dumpCursor(Cursor cursor, StringBuilder sb) { + sb.append(">>>>> Dumping cursor " + cursor + "\n"); + if (cursor != null) { + int startPos = cursor.getPosition(); + + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + dumpCurrentRow(cursor, sb); + } + cursor.moveToPosition(startPos); + } + sb.append("<<<<<\n"); + } + + /** + * Prints the contents of a Cursor to a String. The position is restored + * after printing. + * + * @param cursor the cursor to print + * @return a String that contains the dumped cursor + */ + public static String dumpCursorToString(Cursor cursor) { + StringBuilder sb = new StringBuilder(); + dumpCursor(cursor, sb); + return sb.toString(); + } + + /** + * Prints the contents of a Cursor's current row to System.out. + * + * @param cursor the cursor to print from + */ + public static void dumpCurrentRow(Cursor cursor) { + dumpCurrentRow(cursor, System.out); + } + + /** + * Prints the contents of a Cursor's current row to a PrintSteam. + * + * @param cursor the cursor to print + * @param stream the stream to print to + */ + public static void dumpCurrentRow(Cursor cursor, PrintStream stream) { + String[] cols = cursor.getColumnNames(); + stream.println("" + cursor.getPosition() + " {"); + int length = cols.length; + for (int i = 0; i< length; i++) { + String value; + try { + value = cursor.getString(i); + } catch (SQLiteException e) { + // assume that if the getString threw this exception then the column is not + // representable by a string, e.g. it is a BLOB. + value = "<unprintable>"; + } + stream.println(" " + cols[i] + '=' + value); + } + stream.println("}"); + } + + /** + * Prints the contents of a Cursor's current row to a StringBuilder. + * + * @param cursor the cursor to print + * @param sb the StringBuilder to print to + */ + public static void dumpCurrentRow(Cursor cursor, StringBuilder sb) { + String[] cols = cursor.getColumnNames(); + sb.append("" + cursor.getPosition() + " {\n"); + int length = cols.length; + for (int i = 0; i < length; i++) { + String value; + try { + value = cursor.getString(i); + } catch (SQLiteException e) { + // assume that if the getString threw this exception then the column is not + // representable by a string, e.g. it is a BLOB. + value = "<unprintable>"; + } + sb.append(" " + cols[i] + '=' + value + "\n"); + } + sb.append("}\n"); + } + + /** + * Dump the contents of a Cursor's current row to a String. + * + * @param cursor the cursor to print + * @return a String that contains the dumped cursor row + */ + public static String dumpCurrentRowToString(Cursor cursor) { + StringBuilder sb = new StringBuilder(); + dumpCurrentRow(cursor, sb); + return sb.toString(); + } + + /** + * Reads a String out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The TEXT field to read + * @param values The {@link ContentValues} to put the value into, with the field as the key + */ + public static void cursorStringToContentValues(Cursor cursor, String field, + ContentValues values) { + cursorStringToContentValues(cursor, field, values, field); + } + + /** + * Reads a String out of a field in a Cursor and writes it to an InsertHelper. + * + * @param cursor The cursor to read from + * @param field The TEXT field to read + * @param inserter The InsertHelper to bind into + * @param index the index of the bind entry in the InsertHelper + */ + public static void cursorStringToInsertHelper(Cursor cursor, String field, + InsertHelper inserter, int index) { + inserter.bind(index, cursor.getString(cursor.getColumnIndexOrThrow(field))); + } + + /** + * Reads a String out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The TEXT field to read + * @param values The {@link ContentValues} to put the value into, with the field as the key + * @param key The key to store the value with in the map + */ + public static void cursorStringToContentValues(Cursor cursor, String field, + ContentValues values, String key) { + values.put(key, cursor.getString(cursor.getColumnIndexOrThrow(field))); + } + + /** + * Reads an Integer out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The INTEGER field to read + * @param values The {@link ContentValues} to put the value into, with the field as the key + */ + public static void cursorIntToContentValues(Cursor cursor, String field, ContentValues values) { + cursorIntToContentValues(cursor, field, values, field); + } + + /** + * Reads a Integer out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The INTEGER field to read + * @param values The {@link ContentValues} to put the value into, with the field as the key + * @param key The key to store the value with in the map + */ + public static void cursorIntToContentValues(Cursor cursor, String field, ContentValues values, + String key) { + int colIndex = cursor.getColumnIndex(field); + if (!cursor.isNull(colIndex)) { + values.put(key, cursor.getInt(colIndex)); + } else { + values.put(key, (Integer) null); + } + } + + /** + * Reads a Long out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The INTEGER field to read + * @param values The {@link ContentValues} to put the value into, with the field as the key + */ + public static void cursorLongToContentValues(Cursor cursor, String field, ContentValues values) + { + cursorLongToContentValues(cursor, field, values, field); + } + + /** + * Reads a Long out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The INTEGER field to read + * @param values The {@link ContentValues} to put the value into + * @param key The key to store the value with in the map + */ + public static void cursorLongToContentValues(Cursor cursor, String field, ContentValues values, + String key) { + int colIndex = cursor.getColumnIndex(field); + if (!cursor.isNull(colIndex)) { + Long value = Long.valueOf(cursor.getLong(colIndex)); + values.put(key, value); + } else { + values.put(key, (Long) null); + } + } + + /** + * Reads a Double out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The REAL field to read + * @param values The {@link ContentValues} to put the value into + */ + public static void cursorDoubleToCursorValues(Cursor cursor, String field, ContentValues values) + { + cursorDoubleToContentValues(cursor, field, values, field); + } + + /** + * Reads a Double out of a field in a Cursor and writes it to a Map. + * + * @param cursor The cursor to read from + * @param field The REAL field to read + * @param values The {@link ContentValues} to put the value into + * @param key The key to store the value with in the map + */ + public static void cursorDoubleToContentValues(Cursor cursor, String field, + ContentValues values, String key) { + int colIndex = cursor.getColumnIndex(field); + if (!cursor.isNull(colIndex)) { + values.put(key, cursor.getDouble(colIndex)); + } else { + values.put(key, (Double) null); + } + } + + /** + * Read the entire contents of a cursor row and store them in a ContentValues. + * + * @param cursor the cursor to read from. + * @param values the {@link ContentValues} to put the row into. + */ + public static void cursorRowToContentValues(Cursor cursor, ContentValues values) { + String[] columns = cursor.getColumnNames(); + int length = columns.length; + for (int i = 0; i < length; i++) { + if (cursor.getType(i) == Cursor.FIELD_TYPE_BLOB) { + values.put(columns[i], cursor.getBlob(i)); + } else { + values.put(columns[i], cursor.getString(i)); + } + } + } + + /** + * Picks a start position for {@link Cursor#fillWindow} such that the + * window will contain the requested row and a useful range of rows + * around it. + * + * When the data set is too large to fit in a cursor window, seeking the + * cursor can become a very expensive operation since we have to run the + * query again when we move outside the bounds of the current window. + * + * We try to choose a start position for the cursor window such that + * 1/3 of the window's capacity is used to hold rows before the requested + * position and 2/3 of the window's capacity is used to hold rows after the + * requested position. + * + * @param cursorPosition The row index of the row we want to get. + * @param cursorWindowCapacity The estimated number of rows that can fit in + * a cursor window, or 0 if unknown. + * @return The recommended start position, always less than or equal to + * the requested row. + * @hide + */ + public static int cursorPickFillWindowStartPosition( + int cursorPosition, int cursorWindowCapacity) { + return Math.max(cursorPosition - cursorWindowCapacity / 3, 0); + } + + /** + * Query the table for the number of rows in the table. + * @param db the database the table is in + * @param table the name of the table to query + * @return the number of rows in the table + */ + public static long queryNumEntries(SQLiteDatabase db, String table) { + return queryNumEntries(db, table, null, null); + } + + /** + * Query the table for the number of rows in the table. + * @param db the database the table is in + * @param table the name of the table to query + * @param selection A filter declaring which rows to return, + * formatted as an SQL WHERE clause (excluding the WHERE itself). + * Passing null will count all rows for the given table + * @return the number of rows in the table filtered by the selection + */ + public static long queryNumEntries(SQLiteDatabase db, String table, String selection) { + return queryNumEntries(db, table, selection, null); + } + + /** + * Query the table for the number of rows in the table. + * @param db the database the table is in + * @param table the name of the table to query + * @param selection A filter declaring which rows to return, + * formatted as an SQL WHERE clause (excluding the WHERE itself). + * Passing null will count all rows for the given table + * @param selectionArgs You may include ?s in selection, + * which will be replaced by the values from selectionArgs, + * in order that they appear in the selection. + * The values will be bound as Strings. + * @return the number of rows in the table filtered by the selection + */ + public static long queryNumEntries(SQLiteDatabase db, String table, String selection, + String[] selectionArgs) { + String s = (!TextUtils.isEmpty(selection)) ? " where " + selection : ""; + return longForQuery(db, "select count(*) from " + table + s, + selectionArgs); + } + + /** + * Query the table to check whether a table is empty or not + * @param db the database the table is in + * @param table the name of the table to query + * @return True if the table is empty + * @hide + */ + public static boolean queryIsEmpty(SQLiteDatabase db, String table) { + long isEmpty = longForQuery(db, "select exists(select 1 from " + table + ")", null); + return isEmpty == 0; + } + + /** + * Utility method to run the query on the db and return the value in the + * first column of the first row. + */ + public static long longForQuery(SQLiteDatabase db, String query, String[] selectionArgs) { + SQLiteStatement prog = db.compileStatement(query); + try { + return longForQuery(prog, selectionArgs); + } finally { + prog.close(); + } + } + + /** + * Utility method to run the pre-compiled query and return the value in the + * first column of the first row. + */ + public static long longForQuery(SQLiteStatement prog, String[] selectionArgs) { + prog.bindAllArgsAsStrings(selectionArgs); + return prog.simpleQueryForLong(); + } + + /** + * Utility method to run the query on the db and return the value in the + * first column of the first row. + */ + public static String stringForQuery(SQLiteDatabase db, String query, String[] selectionArgs) { + SQLiteStatement prog = db.compileStatement(query); + try { + return stringForQuery(prog, selectionArgs); + } finally { + prog.close(); + } + } + + /** + * Utility method to run the pre-compiled query and return the value in the + * first column of the first row. + */ + public static String stringForQuery(SQLiteStatement prog, String[] selectionArgs) { + prog.bindAllArgsAsStrings(selectionArgs); + return prog.simpleQueryForString(); + } + + /** + * Utility method to run the query on the db and return the blob value in the + * first column of the first row. + * + * @return A read-only file descriptor for a copy of the blob value. + */ + public static ParcelFileDescriptor blobFileDescriptorForQuery(SQLiteDatabase db, + String query, String[] selectionArgs) { + SQLiteStatement prog = db.compileStatement(query); + try { + return blobFileDescriptorForQuery(prog, selectionArgs); + } finally { + prog.close(); + } + } + + /** + * Utility method to run the pre-compiled query and return the blob value in the + * first column of the first row. + * + * @return A read-only file descriptor for a copy of the blob value. + */ + public static ParcelFileDescriptor blobFileDescriptorForQuery(SQLiteStatement prog, + String[] selectionArgs) { + prog.bindAllArgsAsStrings(selectionArgs); + return prog.simpleQueryForBlobFileDescriptor(); + } + + /** + * Reads a String out of a column in a Cursor and writes it to a ContentValues. + * Adds nothing to the ContentValues if the column isn't present or if its value is null. + * + * @param cursor The cursor to read from + * @param column The column to read + * @param values The {@link ContentValues} to put the value into + */ + public static void cursorStringToContentValuesIfPresent(Cursor cursor, ContentValues values, + String column) { + final int index = cursor.getColumnIndex(column); + if (index != -1 && !cursor.isNull(index)) { + values.put(column, cursor.getString(index)); + } + } + + /** + * Reads a Long out of a column in a Cursor and writes it to a ContentValues. + * Adds nothing to the ContentValues if the column isn't present or if its value is null. + * + * @param cursor The cursor to read from + * @param column The column to read + * @param values The {@link ContentValues} to put the value into + */ + public static void cursorLongToContentValuesIfPresent(Cursor cursor, ContentValues values, + String column) { + final int index = cursor.getColumnIndex(column); + if (index != -1 && !cursor.isNull(index)) { + values.put(column, cursor.getLong(index)); + } + } + + /** + * Reads a Short out of a column in a Cursor and writes it to a ContentValues. + * Adds nothing to the ContentValues if the column isn't present or if its value is null. + * + * @param cursor The cursor to read from + * @param column The column to read + * @param values The {@link ContentValues} to put the value into + */ + public static void cursorShortToContentValuesIfPresent(Cursor cursor, ContentValues values, + String column) { + final int index = cursor.getColumnIndex(column); + if (index != -1 && !cursor.isNull(index)) { + values.put(column, cursor.getShort(index)); + } + } + + /** + * Reads a Integer out of a column in a Cursor and writes it to a ContentValues. + * Adds nothing to the ContentValues if the column isn't present or if its value is null. + * + * @param cursor The cursor to read from + * @param column The column to read + * @param values The {@link ContentValues} to put the value into + */ + public static void cursorIntToContentValuesIfPresent(Cursor cursor, ContentValues values, + String column) { + final int index = cursor.getColumnIndex(column); + if (index != -1 && !cursor.isNull(index)) { + values.put(column, cursor.getInt(index)); + } + } + + /** + * Reads a Float out of a column in a Cursor and writes it to a ContentValues. + * Adds nothing to the ContentValues if the column isn't present or if its value is null. + * + * @param cursor The cursor to read from + * @param column The column to read + * @param values The {@link ContentValues} to put the value into + */ + public static void cursorFloatToContentValuesIfPresent(Cursor cursor, ContentValues values, + String column) { + final int index = cursor.getColumnIndex(column); + if (index != -1 && !cursor.isNull(index)) { + values.put(column, cursor.getFloat(index)); + } + } + + /** + * Reads a Double out of a column in a Cursor and writes it to a ContentValues. + * Adds nothing to the ContentValues if the column isn't present or if its value is null. + * + * @param cursor The cursor to read from + * @param column The column to read + * @param values The {@link ContentValues} to put the value into + */ + public static void cursorDoubleToContentValuesIfPresent(Cursor cursor, ContentValues values, + String column) { + final int index = cursor.getColumnIndex(column); + if (index != -1 && !cursor.isNull(index)) { + values.put(column, cursor.getDouble(index)); + } + } + + /** + * This class allows users to do multiple inserts into a table using + * the same statement. + * <p> + * This class is not thread-safe. + * </p> + * + * @deprecated Use {@link SQLiteStatement} instead. + */ + @Deprecated + public static class InsertHelper { + private final SQLiteDatabase mDb; + private final String mTableName; + private HashMap<String, Integer> mColumns; + private String mInsertSQL = null; + private SQLiteStatement mInsertStatement = null; + private SQLiteStatement mReplaceStatement = null; + private SQLiteStatement mPreparedStatement = null; + + /** + * {@hide} + * + * These are the columns returned by sqlite's "PRAGMA + * table_info(...)" command that we depend on. + */ + public static final int TABLE_INFO_PRAGMA_COLUMNNAME_INDEX = 1; + + /** + * This field was accidentally exposed in earlier versions of the platform + * so we can hide it but we can't remove it. + * + * @hide + */ + public static final int TABLE_INFO_PRAGMA_DEFAULT_INDEX = 4; + + /** + * @param db the SQLiteDatabase to insert into + * @param tableName the name of the table to insert into + */ + public InsertHelper(SQLiteDatabase db, String tableName) { + mDb = db; + mTableName = tableName; + } + + private void buildSQL() throws SQLException { + StringBuilder sb = new StringBuilder(128); + sb.append("INSERT INTO "); + sb.append(mTableName); + sb.append(" ("); + + StringBuilder sbv = new StringBuilder(128); + sbv.append("VALUES ("); + + int i = 1; + Cursor cur = null; + try { + cur = mDb.rawQuery("PRAGMA table_info(" + mTableName + ")", null); + mColumns = new HashMap<String, Integer>(cur.getCount()); + while (cur.moveToNext()) { + String columnName = cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX); + String defaultValue = cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX); + + mColumns.put(columnName, i); + sb.append("'"); + sb.append(columnName); + sb.append("'"); + + if (defaultValue == null) { + sbv.append("?"); + } else { + sbv.append("COALESCE(?, "); + sbv.append(defaultValue); + sbv.append(")"); + } + + sb.append(i == cur.getCount() ? ") " : ", "); + sbv.append(i == cur.getCount() ? ");" : ", "); + ++i; + } + } finally { + if (cur != null) cur.close(); + } + + sb.append(sbv); + + mInsertSQL = sb.toString(); + if (DEBUG) Log.v(TAG, "insert statement is " + mInsertSQL); + } + + private SQLiteStatement getStatement(boolean allowReplace) throws SQLException { + if (allowReplace) { + if (mReplaceStatement == null) { + if (mInsertSQL == null) buildSQL(); + // chop "INSERT" off the front and prepend "INSERT OR REPLACE" instead. + String replaceSQL = "INSERT OR REPLACE" + mInsertSQL.substring(6); + mReplaceStatement = mDb.compileStatement(replaceSQL); + } + return mReplaceStatement; + } else { + if (mInsertStatement == null) { + if (mInsertSQL == null) buildSQL(); + mInsertStatement = mDb.compileStatement(mInsertSQL); + } + return mInsertStatement; + } + } + + /** + * Performs an insert, adding a new row with the given values. + * + * @param values the set of values with which to populate the + * new row + * @param allowReplace if true, the statement does "INSERT OR + * REPLACE" instead of "INSERT", silently deleting any + * previously existing rows that would cause a conflict + * + * @return the row ID of the newly inserted row, or -1 if an + * error occurred + */ + private long insertInternal(ContentValues values, boolean allowReplace) { + // Start a transaction even though we don't really need one. + // This is to help maintain compatibility with applications that + // access InsertHelper from multiple threads even though they never should have. + // The original code used to lock the InsertHelper itself which was prone + // to deadlocks. Starting a transaction achieves the same mutual exclusion + // effect as grabbing a lock but without the potential for deadlocks. + mDb.beginTransactionNonExclusive(); + try { + SQLiteStatement stmt = getStatement(allowReplace); + stmt.clearBindings(); + if (DEBUG) Log.v(TAG, "--- inserting in table " + mTableName); + for (Map.Entry<String, Object> e: values.valueSet()) { + final String key = e.getKey(); + int i = getColumnIndex(key); + DatabaseUtils.bindObjectToProgram(stmt, i, e.getValue()); + if (DEBUG) { + Log.v(TAG, "binding " + e.getValue() + " to column " + + i + " (" + key + ")"); + } + } + long result = stmt.executeInsert(); + mDb.setTransactionSuccessful(); + return result; + } catch (SQLException e) { + Log.e(TAG, "Error inserting " + values + " into table " + mTableName, e); + return -1; + } finally { + mDb.endTransaction(); + } + } + + /** + * Returns the index of the specified column. This is index is suitagble for use + * in calls to bind(). + * @param key the column name + * @return the index of the column + */ + public int getColumnIndex(String key) { + getStatement(false); + final Integer index = mColumns.get(key); + if (index == null) { + throw new IllegalArgumentException("column '" + key + "' is invalid"); + } + return index; + } + + /** + * Bind the value to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + * @param value the value to bind + */ + public void bind(int index, double value) { + mPreparedStatement.bindDouble(index, value); + } + + /** + * Bind the value to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + * @param value the value to bind + */ + public void bind(int index, float value) { + mPreparedStatement.bindDouble(index, value); + } + + /** + * Bind the value to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + * @param value the value to bind + */ + public void bind(int index, long value) { + mPreparedStatement.bindLong(index, value); + } + + /** + * Bind the value to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + * @param value the value to bind + */ + public void bind(int index, int value) { + mPreparedStatement.bindLong(index, value); + } + + /** + * Bind the value to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + * @param value the value to bind + */ + public void bind(int index, boolean value) { + mPreparedStatement.bindLong(index, value ? 1 : 0); + } + + /** + * Bind null to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + */ + public void bindNull(int index) { + mPreparedStatement.bindNull(index); + } + + /** + * Bind the value to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + * @param value the value to bind + */ + public void bind(int index, byte[] value) { + if (value == null) { + mPreparedStatement.bindNull(index); + } else { + mPreparedStatement.bindBlob(index, value); + } + } + + /** + * Bind the value to an index. A prepareForInsert() or prepareForReplace() + * without a matching execute() must have already have been called. + * @param index the index of the slot to which to bind + * @param value the value to bind + */ + public void bind(int index, String value) { + if (value == null) { + mPreparedStatement.bindNull(index); + } else { + mPreparedStatement.bindString(index, value); + } + } + + /** + * Performs an insert, adding a new row with the given values. + * If the table contains conflicting rows, an error is + * returned. + * + * @param values the set of values with which to populate the + * new row + * + * @return the row ID of the newly inserted row, or -1 if an + * error occurred + */ + public long insert(ContentValues values) { + return insertInternal(values, false); + } + + /** + * Execute the previously prepared insert or replace using the bound values + * since the last call to prepareForInsert or prepareForReplace. + * + * <p>Note that calling bind() and then execute() is not thread-safe. The only thread-safe + * way to use this class is to call insert() or replace(). + * + * @return the row ID of the newly inserted row, or -1 if an + * error occurred + */ + public long execute() { + if (mPreparedStatement == null) { + throw new IllegalStateException("you must prepare this inserter before calling " + + "execute"); + } + try { + if (DEBUG) Log.v(TAG, "--- doing insert or replace in table " + mTableName); + return mPreparedStatement.executeInsert(); + } catch (SQLException e) { + Log.e(TAG, "Error executing InsertHelper with table " + mTableName, e); + return -1; + } finally { + // you can only call this once per prepare + mPreparedStatement = null; + } + } + + /** + * Prepare the InsertHelper for an insert. The pattern for this is: + * <ul> + * <li>prepareForInsert() + * <li>bind(index, value); + * <li>bind(index, value); + * <li>... + * <li>bind(index, value); + * <li>execute(); + * </ul> + */ + public void prepareForInsert() { + mPreparedStatement = getStatement(false); + mPreparedStatement.clearBindings(); + } + + /** + * Prepare the InsertHelper for a replace. The pattern for this is: + * <ul> + * <li>prepareForReplace() + * <li>bind(index, value); + * <li>bind(index, value); + * <li>... + * <li>bind(index, value); + * <li>execute(); + * </ul> + */ + public void prepareForReplace() { + mPreparedStatement = getStatement(true); + mPreparedStatement.clearBindings(); + } + + /** + * Performs an insert, adding a new row with the given values. + * If the table contains conflicting rows, they are deleted + * and replaced with the new row. + * + * @param values the set of values with which to populate the + * new row + * + * @return the row ID of the newly inserted row, or -1 if an + * error occurred + */ + public long replace(ContentValues values) { + return insertInternal(values, true); + } + + /** + * Close this object and release any resources associated with + * it. The behavior of calling <code>insert()</code> after + * calling this method is undefined. + */ + public void close() { + if (mInsertStatement != null) { + mInsertStatement.close(); + mInsertStatement = null; + } + if (mReplaceStatement != null) { + mReplaceStatement.close(); + mReplaceStatement = null; + } + mInsertSQL = null; + mColumns = null; + } + } + + /** + * Creates a db and populates it with the sql statements in sqlStatements. + * + * @param context the context to use to create the db + * @param dbName the name of the db to create + * @param dbVersion the version to set on the db + * @param sqlStatements the statements to use to populate the db. This should be a single string + * of the form returned by sqlite3's <tt>.dump</tt> command (statements separated by + * semicolons) + */ + static public void createDbFromSqlStatements( + Context context, String dbName, int dbVersion, String sqlStatements) { + + File f = context.getDatabasePath(dbName); + f.getParentFile().mkdirs(); + SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, null); + + // TODO: this is not quite safe since it assumes that all semicolons at the end of a line + // terminate statements. It is possible that a text field contains ;\n. We will have to fix + // this if that turns out to be a problem. + String[] statements = TextUtils.split(sqlStatements, ";\n"); + for (String statement : statements) { + if (TextUtils.isEmpty(statement)) continue; + db.execSQL(statement); + } + db.setVersion(dbVersion); + db.close(); + } + + /** + * Returns one of the following which represent the type of the given SQL statement. + * <ol> + * <li>{@link #STATEMENT_SELECT}</li> + * <li>{@link #STATEMENT_UPDATE}</li> + * <li>{@link #STATEMENT_ATTACH}</li> + * <li>{@link #STATEMENT_BEGIN}</li> + * <li>{@link #STATEMENT_COMMIT}</li> + * <li>{@link #STATEMENT_ABORT}</li> + * <li>{@link #STATEMENT_OTHER}</li> + * </ol> + * @param sql the SQL statement whose type is returned by this method + * @return one of the values listed above + */ + public static int getSqlStatementType(String sql) { + sql = sql.trim(); + if (sql.length() < 3) { + return STATEMENT_OTHER; + } + String prefixSql = sql.substring(0, 3).toUpperCase(Locale.ROOT); + if (prefixSql.equals("SEL")) { + return STATEMENT_SELECT; + } else if (prefixSql.equals("INS") || + prefixSql.equals("UPD") || + prefixSql.equals("REP") || + prefixSql.equals("DEL")) { + return STATEMENT_UPDATE; + } else if (prefixSql.equals("ATT")) { + return STATEMENT_ATTACH; + } else if (prefixSql.equals("COM")) { + return STATEMENT_COMMIT; + } else if (prefixSql.equals("END")) { + return STATEMENT_COMMIT; + } else if (prefixSql.equals("ROL")) { + return STATEMENT_ABORT; + } else if (prefixSql.equals("BEG")) { + return STATEMENT_BEGIN; + } else if (prefixSql.equals("PRA")) { + return STATEMENT_PRAGMA; + } else if (prefixSql.equals("CRE") || prefixSql.equals("DRO") || + prefixSql.equals("ALT")) { + return STATEMENT_DDL; + } else if (prefixSql.equals("ANA") || prefixSql.equals("DET")) { + return STATEMENT_UNPREPARED; + } + return STATEMENT_OTHER; + } + + /** + * Appends one set of selection args to another. This is useful when adding a selection + * argument to a user provided set. + */ + public static String[] appendSelectionArgs(String[] originalValues, String[] newValues) { + if (originalValues == null || originalValues.length == 0) { + return newValues; + } + String[] result = new String[originalValues.length + newValues.length ]; + System.arraycopy(originalValues, 0, result, 0, originalValues.length); + System.arraycopy(newValues, 0, result, originalValues.length, newValues.length); + return result; + } + + /** + * Returns column index of "_id" column, or -1 if not found. + * @hide + */ + public static int findRowIdColumnIndex(String[] columnNames) { + int length = columnNames.length; + for (int i = 0; i < length; i++) { + if (columnNames[i].equals("_id")) { + return i; + } + } + return -1; + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/DefaultDatabaseErrorHandler.java b/android_studio/app/src/main/java/org/sqlite/database/DefaultDatabaseErrorHandler.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database; + +import java.io.File; +import java.util.List; + +import org.sqlite.database.sqlite.SQLiteDatabase; +import org.sqlite.database.sqlite.SQLiteException; +import android.util.Log; +import android.util.Pair; + +/** + * Default class used to define the action to take when database corruption is reported + * by sqlite. + * <p> + * An application can specify an implementation of {@link DatabaseErrorHandler} on the + * following: + * <ul> + * <li>{@link SQLiteDatabase#openOrCreateDatabase(String, + * android.database.sqlite.SQLiteDatabase.CursorFactory, DatabaseErrorHandler)}</li> + * <li>{@link SQLiteDatabase#openDatabase(String, + * android.database.sqlite.SQLiteDatabase.CursorFactory, int, DatabaseErrorHandler)}</li> + * </ul> + * The specified {@link DatabaseErrorHandler} is used to handle database corruption errors, if they + * occur. + * <p> + * If null is specified for the DatabaseErrorHandler param in the above calls, this class is used + * as the default {@link DatabaseErrorHandler}. + */ +public final class DefaultDatabaseErrorHandler implements DatabaseErrorHandler { + + private static final String TAG = "DefaultDatabaseErrorHandler"; + + /** + * defines the default method to be invoked when database corruption is detected. + * @param dbObj the {@link SQLiteDatabase} object representing the database on which corruption + * is detected. + */ + public void onCorruption(SQLiteDatabase dbObj) { + Log.e(TAG, "Corruption reported by sqlite on database: " + dbObj.getPath()); + + // If this is a SEE build, do not delete any database files. + // It may be that the user has specified an incorrect password. + if( SQLiteDatabase.hasCodec() ) return; + + // is the corruption detected even before database could be 'opened'? + if (!dbObj.isOpen()) { + // database files are not even openable. delete this database file. + // NOTE if the database has attached databases, then any of them could be corrupt. + // and not deleting all of them could cause corrupted database file to remain and + // make the application crash on database open operation. To avoid this problem, + // the application should provide its own {@link DatabaseErrorHandler} impl class + // to delete ALL files of the database (including the attached databases). + deleteDatabaseFile(dbObj.getPath()); + return; + } + + List<Pair<String, String>> attachedDbs = null; + try { + // Close the database, which will cause subsequent operations to fail. + // before that, get the attached database list first. + try { + attachedDbs = dbObj.getAttachedDbs(); + } catch (SQLiteException e) { + /* ignore */ + } + try { + dbObj.close(); + } catch (SQLiteException e) { + /* ignore */ + } + } finally { + // Delete all files of this corrupt database and/or attached databases + if (attachedDbs != null) { + for (Pair<String, String> p : attachedDbs) { + deleteDatabaseFile(p.second); + } + } else { + // attachedDbs = null is possible when the database is so corrupt that even + // "PRAGMA database_list;" also fails. delete the main database file + deleteDatabaseFile(dbObj.getPath()); + } + } + } + + private void deleteDatabaseFile(String fileName) { + if (fileName.equalsIgnoreCase(":memory:") || fileName.trim().length() == 0) { + return; + } + Log.e(TAG, "deleting the database file: " + fileName); + try { + SQLiteDatabase.deleteDatabase(new File(fileName)); + } catch (Exception e) { + /* print warning and ignore exception */ + Log.w(TAG, "delete failed: " + e.getMessage()); + } + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/SQLException.java b/android_studio/app/src/main/java/org/sqlite/database/SQLException.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database; + +/** + * An exception that indicates there was an error with SQL parsing or execution. + */ +public class SQLException extends RuntimeException { + public SQLException() { + } + + public SQLException(String error) { + super(error); + } + + public SQLException(String error, Throwable cause) { + super(error, cause); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/CloseGuard.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/CloseGuard.java @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; +import android.util.Log; + +/** + * CloseGuard is a mechanism for flagging implicit finalizer cleanup of + * resources that should have been cleaned up by explicit close + * methods (aka "explicit termination methods" in Effective Java). + * <p> + * A simple example: <pre> {@code + * class Foo { + * + * private final CloseGuard guard = CloseGuard.get(); + * + * ... + * + * public Foo() { + * ...; + * guard.open("cleanup"); + * } + * + * public void cleanup() { + * guard.close(); + * ...; + * } + * + * protected void finalize() throws Throwable { + * try { + * if (guard != null) { + * guard.warnIfOpen(); + * } + * cleanup(); + * } finally { + * super.finalize(); + * } + * } + * } + * }</pre> + * + * In usage where the resource to be explicitly cleaned up are + * allocated after object construction, CloseGuard protection can + * be deferred. For example: <pre> {@code + * class Bar { + * + * private final CloseGuard guard = CloseGuard.get(); + * + * ... + * + * public Bar() { + * ...; + * } + * + * public void connect() { + * ...; + * guard.open("cleanup"); + * } + * + * public void cleanup() { + * guard.close(); + * ...; + * } + * + * protected void finalize() throws Throwable { + * try { + * if (guard != null) { + * guard.warnIfOpen(); + * } + * cleanup(); + * } finally { + * super.finalize(); + * } + * } + * } + * }</pre> + * + * When used in a constructor calls to {@code open} should occur at + * the end of the constructor since an exception that would cause + * abrupt termination of the constructor will mean that the user will + * not have a reference to the object to cleanup explicitly. When used + * in a method, the call to {@code open} should occur just after + * resource acquisition. + * + * <p> + * + * Note that the null check on {@code guard} in the finalizer is to + * cover cases where a constructor throws an exception causing the + * {@code guard} to be uninitialized. + * + * @hide + */ +public final class CloseGuard { + + /** + * Instance used when CloseGuard is disabled to avoid allocation. + */ + private static final CloseGuard NOOP = new CloseGuard(); + + /** + * Enabled by default so we can catch issues early in VM startup. + * Note, however, that Android disables this early in its startup, + * but enables it with DropBoxing for system apps on debug builds. + */ + private static volatile boolean ENABLED = true; + + /** + * Hook for customizing how CloseGuard issues are reported. + */ + private static volatile Reporter REPORTER = new DefaultReporter(); + + /** + * Returns a CloseGuard instance. If CloseGuard is enabled, {@code + * #open(String)} can be used to set up the instance to warn on + * failure to close. If CloseGuard is disabled, a non-null no-op + * instance is returned. + */ + public static CloseGuard get() { + if (!ENABLED) { + return NOOP; + } + return new CloseGuard(); + } + + /** + * Used to enable or disable CloseGuard. Note that CloseGuard only + * warns if it is enabled for both allocation and finalization. + */ + public static void setEnabled(boolean enabled) { + ENABLED = enabled; + } + + /** + * Used to replace default Reporter used to warn of CloseGuard + * violations. Must be non-null. + */ + public static void setReporter(Reporter reporter) { + if (reporter == null) { + throw new NullPointerException("reporter == null"); + } + REPORTER = reporter; + } + + /** + * Returns non-null CloseGuard.Reporter. + */ + public static Reporter getReporter() { + return REPORTER; + } + + private CloseGuard() {} + + /** + * If CloseGuard is enabled, {@code open} initializes the instance + * with a warning that the caller should have explicitly called the + * {@code closer} method instead of relying on finalization. + * + * @param closer non-null name of explicit termination method + * @throws NullPointerException if closer is null, regardless of + * whether or not CloseGuard is enabled + */ + public void open(String closer) { + // always perform the check for valid API usage... + if (closer == null) { + throw new NullPointerException("closer == null"); + } + // ...but avoid allocating an allocationSite if disabled + if (this == NOOP || !ENABLED) { + return; + } + String message = "Explicit termination method '" + closer + "' not called"; + allocationSite = new Throwable(message); + } + + private Throwable allocationSite; + + /** + * Marks this CloseGuard instance as closed to avoid warnings on + * finalization. + */ + public void close() { + allocationSite = null; + } + + /** + * If CloseGuard is enabled, logs a warning if the caller did not + * properly cleanup by calling an explicit close method + * before finalization. If CloseGuard is disabled, no action is + * performed. + */ + public void warnIfOpen() { + if (allocationSite == null || !ENABLED) { + return; + } + + String message = + ("A resource was acquired at attached stack trace but never released. " + + "See java.io.Closeable for information on avoiding resource leaks."); + + REPORTER.report(message, allocationSite); + } + + /** + * Interface to allow customization of reporting behavior. + */ + public static interface Reporter { + public void report (String message, Throwable allocationSite); + } + + /** + * Default Reporter which reports CloseGuard violations to the log. + */ + private static final class DefaultReporter implements Reporter { + @Override public void report (String message, Throwable allocationSite) { + Log.w(message, allocationSite); + } + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/DatabaseObjectNotClosedException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/DatabaseObjectNotClosedException.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * An exception that indicates that garbage-collector is finalizing a database object + * that is not explicitly closed + * @hide + */ +public class DatabaseObjectNotClosedException extends RuntimeException { + private static final String s = "Application did not close the cursor or database object " + + "that was opened here"; + + public DatabaseObjectNotClosedException() { + super(s); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteAbortException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteAbortException.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * An exception that indicates that the SQLite program was aborted. + * This can happen either through a call to ABORT in a trigger, + * or as the result of using the ABORT conflict clause. + */ +public class SQLiteAbortException extends SQLiteException { + public SQLiteAbortException() {} + + public SQLiteAbortException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteAccessPermException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteAccessPermException.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * This exception class is used when sqlite can't access the database file + * due to lack of permissions on the file. + */ +public class SQLiteAccessPermException extends SQLiteException { + public SQLiteAccessPermException() {} + + public SQLiteAccessPermException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * Thrown if the the bind or column parameter index is out of range + */ +public class SQLiteBindOrColumnIndexOutOfRangeException extends SQLiteException { + public SQLiteBindOrColumnIndexOutOfRangeException() {} + + public SQLiteBindOrColumnIndexOutOfRangeException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteBlobTooBigException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteBlobTooBigException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +public class SQLiteBlobTooBigException extends SQLiteException { + public SQLiteBlobTooBigException() {} + + public SQLiteBlobTooBigException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCantOpenDatabaseException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCantOpenDatabaseException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +public class SQLiteCantOpenDatabaseException extends SQLiteException { + public SQLiteCantOpenDatabaseException() {} + + public SQLiteCantOpenDatabaseException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteClosable.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteClosable.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import java.io.Closeable; + +/** + * An object created from a SQLiteDatabase that can be closed. + * + * This class implements a primitive reference counting scheme for database objects. + */ +public abstract class SQLiteClosable implements Closeable { + private int mReferenceCount = 1; + + /** + * Called when the last reference to the object was released by + * a call to {@link #releaseReference()} or {@link #close()}. + */ + protected abstract void onAllReferencesReleased(); + + /** + * Called when the last reference to the object was released by + * a call to {@link #releaseReferenceFromContainer()}. + * + * @deprecated Do not use. + */ + @Deprecated + protected void onAllReferencesReleasedFromContainer() { + onAllReferencesReleased(); + } + + /** + * Acquires a reference to the object. + * + * @throws IllegalStateException if the last reference to the object has already + * been released. + */ + public void acquireReference() { + synchronized(this) { + if (mReferenceCount <= 0) { + throw new IllegalStateException( + "attempt to re-open an already-closed object: " + this); + } + mReferenceCount++; + } + } + + /** + * Releases a reference to the object, closing the object if the last reference + * was released. + * + * @see #onAllReferencesReleased() + */ + public void releaseReference() { + boolean refCountIsZero = false; + synchronized(this) { + refCountIsZero = --mReferenceCount == 0; + } + if (refCountIsZero) { + onAllReferencesReleased(); + } + } + + /** + * Releases a reference to the object that was owned by the container of the object, + * closing the object if the last reference was released. + * + * @see #onAllReferencesReleasedFromContainer() + * @deprecated Do not use. + */ + @Deprecated + public void releaseReferenceFromContainer() { + boolean refCountIsZero = false; + synchronized(this) { + refCountIsZero = --mReferenceCount == 0; + } + if (refCountIsZero) { + onAllReferencesReleasedFromContainer(); + } + } + + /** + * Releases a reference to the object, closing the object if the last reference + * was released. + * + * Calling this method is equivalent to calling {@link #releaseReference}. + * + * @see #releaseReference() + * @see #onAllReferencesReleased() + */ + public void close() { + releaseReference(); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteConnection.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteConnection.java @@ -0,0 +1,1526 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import org.sqlite.database.sqlite.CloseGuard; + +import android.database.Cursor; +import android.database.CursorWindow; +import org.sqlite.database.DatabaseUtils; +import org.sqlite.database.sqlite.SQLiteDebug.DbStats; +import android.os.CancellationSignal; +import android.os.OperationCanceledException; +import android.os.ParcelFileDescriptor; +import android.os.SystemClock; +import android.util.Log; +import android.util.LruCache; +import android.util.Printer; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Represents a SQLite database connection. + * Each connection wraps an instance of a native <code>sqlite3</code> object. + * <p> + * When database connection pooling is enabled, there can be multiple active + * connections to the same database. Otherwise there is typically only one + * connection per database. + * </p><p> + * When the SQLite WAL feature is enabled, multiple readers and one writer + * can concurrently access the database. Without WAL, readers and writers + * are mutually exclusive. + * </p> + * + * <h2>Ownership and concurrency guarantees</h2> + * <p> + * Connection objects are not thread-safe. They are acquired as needed to + * perform a database operation and are then returned to the pool. At any + * given time, a connection is either owned and used by a {@link SQLiteSession} + * object or the {@link SQLiteConnectionPool}. Those classes are + * responsible for serializing operations to guard against concurrent + * use of a connection. + * </p><p> + * The guarantee of having a single owner allows this class to be implemented + * without locks and greatly simplifies resource management. + * </p> + * + * <h2>Encapsulation guarantees</h2> + * <p> + * The connection object object owns *all* of the SQLite related native + * objects that are associated with the connection. What's more, there are + * no other objects in the system that are capable of obtaining handles to + * those native objects. Consequently, when the connection is closed, we do + * not have to worry about what other components might have references to + * its associated SQLite state -- there are none. + * </p><p> + * Encapsulation is what ensures that the connection object's + * lifecycle does not become a tortured mess of finalizers and reference + * queues. + * </p> + * + * <h2>Reentrance</h2> + * <p> + * This class must tolerate reentrant execution of SQLite operations because + * triggers may call custom SQLite functions that perform additional queries. + * </p> + * + * @hide + */ +public final class SQLiteConnection implements CancellationSignal.OnCancelListener { + private static final String TAG = "SQLiteConnection"; + private static final boolean DEBUG = false; + + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + private final CloseGuard mCloseGuard = CloseGuard.get(); + + private final SQLiteConnectionPool mPool; + private final SQLiteDatabaseConfiguration mConfiguration; + private final int mConnectionId; + private final boolean mIsPrimaryConnection; + private final boolean mIsReadOnlyConnection; + private final PreparedStatementCache mPreparedStatementCache; + private PreparedStatement mPreparedStatementPool; + + // The recent operations log. + private final OperationLog mRecentOperations = new OperationLog(); + + // The native SQLiteConnection pointer. (FOR INTERNAL USE ONLY) + private long mConnectionPtr; + + private boolean mOnlyAllowReadOnlyOperations; + + // The number of times attachCancellationSignal has been called. + // Because SQLite statement execution can be reentrant, we keep track of how many + // times we have attempted to attach a cancellation signal to the connection so that + // we can ensure that we detach the signal at the right time. + private int mCancellationSignalAttachCount; + + private static native long nativeOpen(String path, int openFlags, String label, + boolean enableTrace, boolean enableProfile); + private static native void nativeClose(long connectionPtr); + private static native void nativeRegisterCustomFunction(long connectionPtr, + SQLiteCustomFunction function); + private static native void nativeRegisterLocalizedCollators(long connectionPtr, String locale); + private static native long nativePrepareStatement(long connectionPtr, String sql); + private static native void nativeFinalizeStatement(long connectionPtr, long statementPtr); + private static native int nativeGetParameterCount(long connectionPtr, long statementPtr); + private static native boolean nativeIsReadOnly(long connectionPtr, long statementPtr); + private static native int nativeGetColumnCount(long connectionPtr, long statementPtr); + private static native String nativeGetColumnName(long connectionPtr, long statementPtr, + int index); + private static native void nativeBindNull(long connectionPtr, long statementPtr, + int index); + private static native void nativeBindLong(long connectionPtr, long statementPtr, + int index, long value); + private static native void nativeBindDouble(long connectionPtr, long statementPtr, + int index, double value); + private static native void nativeBindString(long connectionPtr, long statementPtr, + int index, String value); + private static native void nativeBindBlob(long connectionPtr, long statementPtr, + int index, byte[] value); + private static native void nativeResetStatementAndClearBindings( + long connectionPtr, long statementPtr); + private static native void nativeExecute(long connectionPtr, long statementPtr); + private static native long nativeExecuteForLong(long connectionPtr, long statementPtr); + private static native String nativeExecuteForString(long connectionPtr, long statementPtr); + private static native int nativeExecuteForBlobFileDescriptor( + long connectionPtr, long statementPtr); + private static native int nativeExecuteForChangedRowCount(long connectionPtr, long statementPtr); + private static native long nativeExecuteForLastInsertedRowId( + long connectionPtr, long statementPtr); + private static native long nativeExecuteForCursorWindow( + long connectionPtr, long statementPtr, CursorWindow win, + int startPos, int requiredPos, boolean countAllRows); + private static native int nativeGetDbLookaside(long connectionPtr); + private static native void nativeCancel(long connectionPtr); + private static native void nativeResetCancel(long connectionPtr, boolean cancelable); + + private static native boolean nativeHasCodec(); + public static boolean hasCodec(){ return nativeHasCodec(); } + + private SQLiteConnection(SQLiteConnectionPool pool, + SQLiteDatabaseConfiguration configuration, + int connectionId, boolean primaryConnection) { + mPool = pool; + mConfiguration = new SQLiteDatabaseConfiguration(configuration); + mConnectionId = connectionId; + mIsPrimaryConnection = primaryConnection; + mIsReadOnlyConnection = (configuration.openFlags & SQLiteDatabase.OPEN_READONLY) != 0; + mPreparedStatementCache = new PreparedStatementCache( + mConfiguration.maxSqlCacheSize); + mCloseGuard.open("close"); + } + + @Override + protected void finalize() throws Throwable { + try { + if (mPool != null && mConnectionPtr != 0) { + mPool.onConnectionLeaked(); + } + + dispose(true); + } finally { + super.finalize(); + } + } + + // Called by SQLiteConnectionPool only. + static SQLiteConnection open(SQLiteConnectionPool pool, + SQLiteDatabaseConfiguration configuration, + int connectionId, boolean primaryConnection) { + SQLiteConnection connection = new SQLiteConnection(pool, configuration, + connectionId, primaryConnection); + try { + connection.open(); + return connection; + } catch (SQLiteException ex) { + connection.dispose(false); + throw ex; + } + } + + // Called by SQLiteConnectionPool only. + // Closes the database closes and releases all of its associated resources. + // Do not call methods on the connection after it is closed. It will probably crash. + void close() { + dispose(false); + } + + private void open() { + mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags, + mConfiguration.label, + SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME); + + setPageSize(); + setForeignKeyModeFromConfiguration(); + setJournalSizeLimit(); + setAutoCheckpointInterval(); + if( !nativeHasCodec() ){ + setWalModeFromConfiguration(); + setLocaleFromConfiguration(); + } + // Register custom functions. + final int functionCount = mConfiguration.customFunctions.size(); + for (int i = 0; i < functionCount; i++) { + SQLiteCustomFunction function = mConfiguration.customFunctions.get(i); + nativeRegisterCustomFunction(mConnectionPtr, function); + } + } + + private void dispose(boolean finalized) { + if (mCloseGuard != null) { + if (finalized) { + mCloseGuard.warnIfOpen(); + } + mCloseGuard.close(); + } + + if (mConnectionPtr != 0) { + final int cookie = mRecentOperations.beginOperation("close", null, null); + try { + mPreparedStatementCache.evictAll(); + nativeClose(mConnectionPtr); + mConnectionPtr = 0; + } finally { + mRecentOperations.endOperation(cookie); + } + } + } + + private void setPageSize() { + if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { + final long newValue = SQLiteGlobal.getDefaultPageSize(); + long value = executeForLong("PRAGMA page_size", null, null); + if (value != newValue) { + execute("PRAGMA page_size=" + newValue, null, null); + } + } + } + + private void setAutoCheckpointInterval() { + if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { + final long newValue = SQLiteGlobal.getWALAutoCheckpoint(); + long value = executeForLong("PRAGMA wal_autocheckpoint", null, null); + if (value != newValue) { + executeForLong("PRAGMA wal_autocheckpoint=" + newValue, null, null); + } + } + } + + private void setJournalSizeLimit() { + if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { + final long newValue = SQLiteGlobal.getJournalSizeLimit(); + long value = executeForLong("PRAGMA journal_size_limit", null, null); + if (value != newValue) { + executeForLong("PRAGMA journal_size_limit=" + newValue, null, null); + } + } + } + + private void setForeignKeyModeFromConfiguration() { + if (!mIsReadOnlyConnection) { + final long newValue = mConfiguration.foreignKeyConstraintsEnabled ? 1 : 0; + long value = executeForLong("PRAGMA foreign_keys", null, null); + if (value != newValue) { + execute("PRAGMA foreign_keys=" + newValue, null, null); + } + } + } + + private void setWalModeFromConfiguration() { + if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) { + if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) { + setJournalMode("WAL"); + setSyncMode(SQLiteGlobal.getWALSyncMode()); + } else { + setJournalMode(SQLiteGlobal.getDefaultJournalMode()); + setSyncMode(SQLiteGlobal.getDefaultSyncMode()); + } + } + } + + private void setSyncMode(String newValue) { + String value = executeForString("PRAGMA synchronous", null, null); + if (!canonicalizeSyncMode(value).equalsIgnoreCase( + canonicalizeSyncMode(newValue))) { + execute("PRAGMA synchronous=" + newValue, null, null); + } + } + + private static String canonicalizeSyncMode(String value) { + if (value.equals("0")) { + return "OFF"; + } else if (value.equals("1")) { + return "NORMAL"; + } else if (value.equals("2")) { + return "FULL"; + } + return value; + } + + private void setJournalMode(String newValue) { + String value = executeForString("PRAGMA journal_mode", null, null); + if (!value.equalsIgnoreCase(newValue)) { + try { + String result = executeForString("PRAGMA journal_mode=" + newValue, null, null); + if (result.equalsIgnoreCase(newValue)) { + return; + } + // PRAGMA journal_mode silently fails and returns the original journal + // mode in some cases if the journal mode could not be changed. + } catch (SQLiteDatabaseLockedException ex) { + // This error (SQLITE_BUSY) occurs if one connection has the database + // open in WAL mode and another tries to change it to non-WAL. + } + // Because we always disable WAL mode when a database is first opened + // (even if we intend to re-enable it), we can encounter problems if + // there is another open connection to the database somewhere. + // This can happen for a variety of reasons such as an application opening + // the same database in multiple processes at the same time or if there is a + // crashing content provider service that the ActivityManager has + // removed from its registry but whose process hasn't quite died yet + // by the time it is restarted in a new process. + // + // If we don't change the journal mode, nothing really bad happens. + // In the worst case, an application that enables WAL might not actually + // get it, although it can still use connection pooling. + Log.w(TAG, "Could not change the database journal mode of '" + + mConfiguration.label + "' from '" + value + "' to '" + newValue + + "' because the database is locked. This usually means that " + + "there are other open connections to the database which prevents " + + "the database from enabling or disabling write-ahead logging mode. " + + "Proceeding without changing the journal mode."); + } + } + + private void setLocaleFromConfiguration() { + if ((mConfiguration.openFlags & SQLiteDatabase.NO_LOCALIZED_COLLATORS) != 0) { + return; + } + + // Register the localized collators. + final String newLocale = mConfiguration.locale.toString(); + nativeRegisterLocalizedCollators(mConnectionPtr, newLocale); + + // If the database is read-only, we cannot modify the android metadata table + // or existing indexes. + if (mIsReadOnlyConnection) { + return; + } + + try { + // Ensure the android metadata table exists. + execute("CREATE TABLE IF NOT EXISTS android_metadata (locale TEXT)", null, null); + + // Check whether the locale was actually changed. + final String oldLocale = executeForString("SELECT locale FROM android_metadata " + + "UNION SELECT NULL ORDER BY locale DESC LIMIT 1", null, null); + if (oldLocale != null && oldLocale.equals(newLocale)) { + return; + } + + // Go ahead and update the indexes using the new locale. + execute("BEGIN", null, null); + boolean success = false; + try { + execute("DELETE FROM android_metadata", null, null); + execute("INSERT INTO android_metadata (locale) VALUES(?)", + new Object[] { newLocale }, null); + execute("REINDEX LOCALIZED", null, null); + success = true; + } finally { + execute(success ? "COMMIT" : "ROLLBACK", null, null); + } + } catch (RuntimeException ex) { + throw new SQLiteException("Failed to change locale for db '" + mConfiguration.label + + "' to '" + newLocale + "'.", ex); + } + } + + public void enableLocalizedCollators(){ + if( nativeHasCodec() ){ + setLocaleFromConfiguration(); + } + } + + // Called by SQLiteConnectionPool only. + void reconfigure(SQLiteDatabaseConfiguration configuration) { + mOnlyAllowReadOnlyOperations = false; + + // Register custom functions. + final int functionCount = configuration.customFunctions.size(); + for (int i = 0; i < functionCount; i++) { + SQLiteCustomFunction function = configuration.customFunctions.get(i); + if (!mConfiguration.customFunctions.contains(function)) { + nativeRegisterCustomFunction(mConnectionPtr, function); + } + } + + // Remember what changed. + boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled + != mConfiguration.foreignKeyConstraintsEnabled; + boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags) + & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0; + boolean localeChanged = !configuration.locale.equals(mConfiguration.locale); + + // Update configuration parameters. + mConfiguration.updateParametersFrom(configuration); + + // Update prepared statement cache size. + // sqlite.org: android.util.LruCache.resize() requires API level 21. + // mPreparedStatementCache.resize(configuration.maxSqlCacheSize); + + // Update foreign key mode. + if (foreignKeyModeChanged) { + setForeignKeyModeFromConfiguration(); + } + + // Update WAL. + if (walModeChanged) { + setWalModeFromConfiguration(); + } + + // Update locale. + if (localeChanged) { + setLocaleFromConfiguration(); + } + } + + // Called by SQLiteConnectionPool only. + // When set to true, executing write operations will throw SQLiteException. + // Preparing statements that might write is ok, just don't execute them. + void setOnlyAllowReadOnlyOperations(boolean readOnly) { + mOnlyAllowReadOnlyOperations = readOnly; + } + + // Called by SQLiteConnectionPool only. + // Returns true if the prepared statement cache contains the specified SQL. + boolean isPreparedStatementInCache(String sql) { + return mPreparedStatementCache.get(sql) != null; + } + + /** + * Gets the unique id of this connection. + * @return The connection id. + */ + public int getConnectionId() { + return mConnectionId; + } + + /** + * Returns true if this is the primary database connection. + * @return True if this is the primary database connection. + */ + public boolean isPrimaryConnection() { + return mIsPrimaryConnection; + } + + /** + * Prepares a statement for execution but does not bind its parameters or execute it. + * <p> + * This method can be used to check for syntax errors during compilation + * prior to execution of the statement. If the {@code outStatementInfo} argument + * is not null, the provided {@link SQLiteStatementInfo} object is populated + * with information about the statement. + * </p><p> + * A prepared statement makes no reference to the arguments that may eventually + * be bound to it, consequently it it possible to cache certain prepared statements + * such as SELECT or INSERT/UPDATE statements. If the statement is cacheable, + * then it will be stored in the cache for later. + * </p><p> + * To take advantage of this behavior as an optimization, the connection pool + * provides a method to acquire a connection that already has a given SQL statement + * in its prepared statement cache so that it is ready for execution. + * </p> + * + * @param sql The SQL statement to prepare. + * @param outStatementInfo The {@link SQLiteStatementInfo} object to populate + * with information about the statement, or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error. + */ + public void prepare(String sql, SQLiteStatementInfo outStatementInfo) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + final int cookie = mRecentOperations.beginOperation("prepare", sql, null); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + if (outStatementInfo != null) { + outStatementInfo.numParameters = statement.mNumParameters; + outStatementInfo.readOnly = statement.mReadOnly; + + final int columnCount = nativeGetColumnCount( + mConnectionPtr, statement.mStatementPtr); + if (columnCount == 0) { + outStatementInfo.columnNames = EMPTY_STRING_ARRAY; + } else { + outStatementInfo.columnNames = new String[columnCount]; + for (int i = 0; i < columnCount; i++) { + outStatementInfo.columnNames[i] = nativeGetColumnName( + mConnectionPtr, statement.mStatementPtr, i); + } + } + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + mRecentOperations.endOperation(cookie); + } + } + + /** + * Executes a statement that does not return a result. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public void execute(String sql, Object[] bindArgs, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + final int cookie = mRecentOperations.beginOperation("execute", sql, bindArgs); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + nativeExecute(mConnectionPtr, statement.mStatementPtr); + } finally { + detachCancellationSignal(cancellationSignal); + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + mRecentOperations.endOperation(cookie); + } + } + + /** + * Executes a statement that returns a single <code>long</code> result. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The value of the first column in the first row of the result set + * as a <code>long</code>, or zero if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public long executeForLong(String sql, Object[] bindArgs, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + final int cookie = mRecentOperations.beginOperation("executeForLong", sql, bindArgs); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + return nativeExecuteForLong(mConnectionPtr, statement.mStatementPtr); + } finally { + detachCancellationSignal(cancellationSignal); + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + mRecentOperations.endOperation(cookie); + } + } + + /** + * Executes a statement that returns a single {@link String} result. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The value of the first column in the first row of the result set + * as a <code>String</code>, or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public String executeForString(String sql, Object[] bindArgs, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + final int cookie = mRecentOperations.beginOperation("executeForString", sql, bindArgs); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + return nativeExecuteForString(mConnectionPtr, statement.mStatementPtr); + } finally { + detachCancellationSignal(cancellationSignal); + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + mRecentOperations.endOperation(cookie); + } + } + + /** + * Executes a statement that returns a single BLOB result as a + * file descriptor to a shared memory region. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The file descriptor for a shared memory region that contains + * the value of the first column in the first row of the result set as a BLOB, + * or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + final int cookie = mRecentOperations.beginOperation("executeForBlobFileDescriptor", + sql, bindArgs); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + int fd = nativeExecuteForBlobFileDescriptor( + mConnectionPtr, statement.mStatementPtr); + return fd >= 0 ? ParcelFileDescriptor.adoptFd(fd) : null; + } finally { + detachCancellationSignal(cancellationSignal); + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + mRecentOperations.endOperation(cookie); + } + } + + /** + * Executes a statement that returns a count of the number of rows + * that were changed. Use for UPDATE or DELETE SQL statements. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The number of rows that were changed. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public int executeForChangedRowCount(String sql, Object[] bindArgs, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + int changedRows = 0; + final int cookie = mRecentOperations.beginOperation("executeForChangedRowCount", + sql, bindArgs); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + changedRows = nativeExecuteForChangedRowCount( + mConnectionPtr, statement.mStatementPtr); + return changedRows; + } finally { + detachCancellationSignal(cancellationSignal); + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + if (mRecentOperations.endOperationDeferLog(cookie)) { + mRecentOperations.logOperation(cookie, "changedRows=" + changedRows); + } + } + } + + /** + * Executes a statement that returns the row id of the last row inserted + * by the statement. Use for INSERT SQL statements. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The row id of the last row that was inserted, or 0 if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public long executeForLastInsertedRowId(String sql, Object[] bindArgs, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + final int cookie = mRecentOperations.beginOperation("executeForLastInsertedRowId", + sql, bindArgs); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + return nativeExecuteForLastInsertedRowId( + mConnectionPtr, statement.mStatementPtr); + } finally { + detachCancellationSignal(cancellationSignal); + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + mRecentOperations.endOperation(cookie); + } + } + + /** + * Executes a statement and populates the specified {@link CursorWindow} + * with a range of results. Returns the number of rows that were counted + * during query execution. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param window The cursor window to clear and fill. + * @param startPos The start position for filling the window. + * @param requiredPos The position of a row that MUST be in the window. + * If it won't fit, then the query should discard part of what it filled + * so that it does. Must be greater than or equal to <code>startPos</code>. + * @param countAllRows True to count all rows that the query would return + * regagless of whether they fit in the window. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The number of rows that were counted during query execution. Might + * not be all rows in the result set unless <code>countAllRows</code> is true. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public int executeForCursorWindow(String sql, Object[] bindArgs, + CursorWindow window, int startPos, int requiredPos, boolean countAllRows, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + if (window == null) { + throw new IllegalArgumentException("window must not be null."); + } + + window.acquireReference(); + try { + int actualPos = -1; + int countedRows = -1; + int filledRows = -1; + final int cookie = mRecentOperations.beginOperation("executeForCursorWindow", + sql, bindArgs); + try { + final PreparedStatement statement = acquirePreparedStatement(sql); + try { + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + final long result = nativeExecuteForCursorWindow( + mConnectionPtr, statement.mStatementPtr, window, + startPos, requiredPos, countAllRows); + actualPos = (int)(result >> 32); + countedRows = (int)result; + filledRows = window.getNumRows(); + window.setStartPosition(actualPos); + return countedRows; + } finally { + detachCancellationSignal(cancellationSignal); + } + } finally { + releasePreparedStatement(statement); + } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; + } finally { + if (mRecentOperations.endOperationDeferLog(cookie)) { + mRecentOperations.logOperation(cookie, "window='" + window + + "', startPos=" + startPos + + ", actualPos=" + actualPos + + ", filledRows=" + filledRows + + ", countedRows=" + countedRows); + } + } + } finally { + window.releaseReference(); + } + } + + private PreparedStatement acquirePreparedStatement(String sql) { + PreparedStatement statement = mPreparedStatementCache.get(sql); + boolean skipCache = false; + if (statement != null) { + if (!statement.mInUse) { + return statement; + } + // The statement is already in the cache but is in use (this statement appears + // to be not only re-entrant but recursive!). So prepare a new copy of the + // statement but do not cache it. + skipCache = true; + } + + final long statementPtr = nativePrepareStatement(mConnectionPtr, sql); + try { + final int numParameters = nativeGetParameterCount(mConnectionPtr, statementPtr); + final int type = DatabaseUtils.getSqlStatementType(sql); + final boolean readOnly = nativeIsReadOnly(mConnectionPtr, statementPtr); + statement = obtainPreparedStatement(sql, statementPtr, numParameters, type, readOnly); + if (!skipCache && isCacheable(type)) { + mPreparedStatementCache.put(sql, statement); + statement.mInCache = true; + } + } catch (RuntimeException ex) { + // Finalize the statement if an exception occurred and we did not add + // it to the cache. If it is already in the cache, then leave it there. + if (statement == null || !statement.mInCache) { + nativeFinalizeStatement(mConnectionPtr, statementPtr); + } + throw ex; + } + statement.mInUse = true; + return statement; + } + + private void releasePreparedStatement(PreparedStatement statement) { + statement.mInUse = false; + if (statement.mInCache) { + try { + nativeResetStatementAndClearBindings(mConnectionPtr, statement.mStatementPtr); + } catch (SQLiteException ex) { + // The statement could not be reset due to an error. Remove it from the cache. + // When remove() is called, the cache will invoke its entryRemoved() callback, + // which will in turn call finalizePreparedStatement() to finalize and + // recycle the statement. + if (DEBUG) { + Log.d(TAG, "Could not reset prepared statement due to an exception. " + + "Removing it from the cache. SQL: " + + trimSqlForDisplay(statement.mSql), ex); + } + + mPreparedStatementCache.remove(statement.mSql); + } + } else { + finalizePreparedStatement(statement); + } + } + + private void finalizePreparedStatement(PreparedStatement statement) { + nativeFinalizeStatement(mConnectionPtr, statement.mStatementPtr); + recyclePreparedStatement(statement); + } + + private void attachCancellationSignal(CancellationSignal cancellationSignal) { + if (cancellationSignal != null) { + cancellationSignal.throwIfCanceled(); + + mCancellationSignalAttachCount += 1; + if (mCancellationSignalAttachCount == 1) { + // Reset cancellation flag before executing the statement. + nativeResetCancel(mConnectionPtr, true /*cancelable*/); + + // After this point, onCancel() may be called concurrently. + cancellationSignal.setOnCancelListener(this); + } + } + } + + private void detachCancellationSignal(CancellationSignal cancellationSignal) { + if (cancellationSignal != null) { + assert mCancellationSignalAttachCount > 0; + + mCancellationSignalAttachCount -= 1; + if (mCancellationSignalAttachCount == 0) { + // After this point, onCancel() cannot be called concurrently. + cancellationSignal.setOnCancelListener(null); + + // Reset cancellation flag after executing the statement. + nativeResetCancel(mConnectionPtr, false /*cancelable*/); + } + } + } + + // CancellationSignal.OnCancelListener callback. + // This method may be called on a different thread than the executing statement. + // However, it will only be called between calls to attachCancellationSignal and + // detachCancellationSignal, while a statement is executing. We can safely assume + // that the SQLite connection is still alive. + @Override + public void onCancel() { + nativeCancel(mConnectionPtr); + } + + private void bindArguments(PreparedStatement statement, Object[] bindArgs) { + final int count = bindArgs != null ? bindArgs.length : 0; + if (count != statement.mNumParameters) { + throw new SQLiteBindOrColumnIndexOutOfRangeException( + "Expected " + statement.mNumParameters + " bind arguments but " + + count + " were provided."); + } + if (count == 0) { + return; + } + + final long statementPtr = statement.mStatementPtr; + for (int i = 0; i < count; i++) { + final Object arg = bindArgs[i]; + switch (DatabaseUtils.getTypeOfObject(arg)) { + case Cursor.FIELD_TYPE_NULL: + nativeBindNull(mConnectionPtr, statementPtr, i + 1); + break; + case Cursor.FIELD_TYPE_INTEGER: + nativeBindLong(mConnectionPtr, statementPtr, i + 1, + ((Number)arg).longValue()); + break; + case Cursor.FIELD_TYPE_FLOAT: + nativeBindDouble(mConnectionPtr, statementPtr, i + 1, + ((Number)arg).doubleValue()); + break; + case Cursor.FIELD_TYPE_BLOB: + nativeBindBlob(mConnectionPtr, statementPtr, i + 1, (byte[])arg); + break; + case Cursor.FIELD_TYPE_STRING: + default: + if (arg instanceof Boolean) { + // Provide compatibility with legacy applications which may pass + // Boolean values in bind args. + nativeBindLong(mConnectionPtr, statementPtr, i + 1, + ((Boolean)arg).booleanValue() ? 1 : 0); + } else { + nativeBindString(mConnectionPtr, statementPtr, i + 1, arg.toString()); + } + break; + } + } + } + + private void throwIfStatementForbidden(PreparedStatement statement) { + if (mOnlyAllowReadOnlyOperations && !statement.mReadOnly) { + throw new SQLiteException("Cannot execute this statement because it " + + "might modify the database but the connection is read-only."); + } + } + + private static boolean isCacheable(int statementType) { + if (statementType == DatabaseUtils.STATEMENT_UPDATE + || statementType == DatabaseUtils.STATEMENT_SELECT) { + return true; + } + return false; + } + + private void applyBlockGuardPolicy(PreparedStatement statement) { + } + + /** + * Dumps debugging information about this connection. + * + * @param printer The printer to receive the dump, not null. + * @param verbose True to dump more verbose information. + */ + public void dump(Printer printer, boolean verbose) { + dumpUnsafe(printer, verbose); + } + + /** + * Dumps debugging information about this connection, in the case where the + * caller might not actually own the connection. + * + * This function is written so that it may be called by a thread that does not + * own the connection. We need to be very careful because the connection state is + * not synchronized. + * + * At worst, the method may return stale or slightly wrong data, however + * it should not crash. This is ok as it is only used for diagnostic purposes. + * + * @param printer The printer to receive the dump, not null. + * @param verbose True to dump more verbose information. + */ + void dumpUnsafe(Printer printer, boolean verbose) { + printer.println("Connection #" + mConnectionId + ":"); + if (verbose) { + printer.println(" connectionPtr: 0x" + Long.toHexString(mConnectionPtr)); + } + printer.println(" isPrimaryConnection: " + mIsPrimaryConnection); + printer.println(" onlyAllowReadOnlyOperations: " + mOnlyAllowReadOnlyOperations); + + mRecentOperations.dump(printer, verbose); + + if (verbose) { + mPreparedStatementCache.dump(printer); + } + } + + /** + * Describes the currently executing operation, in the case where the + * caller might not actually own the connection. + * + * This function is written so that it may be called by a thread that does not + * own the connection. We need to be very careful because the connection state is + * not synchronized. + * + * At worst, the method may return stale or slightly wrong data, however + * it should not crash. This is ok as it is only used for diagnostic purposes. + * + * @return A description of the current operation including how long it has been running, + * or null if none. + */ + String describeCurrentOperationUnsafe() { + return mRecentOperations.describeCurrentOperation(); + } + + /** + * Collects statistics about database connection memory usage. + * + * @param dbStatsList The list to populate. + */ + void collectDbStats(ArrayList<DbStats> dbStatsList) { + // Get information about the main database. + int lookaside = nativeGetDbLookaside(mConnectionPtr); + long pageCount = 0; + long pageSize = 0; + try { + pageCount = executeForLong("PRAGMA page_count;", null, null); + pageSize = executeForLong("PRAGMA page_size;", null, null); + } catch (SQLiteException ex) { + // Ignore. + } + dbStatsList.add(getMainDbStatsUnsafe(lookaside, pageCount, pageSize)); + + // Get information about attached databases. + // We ignore the first row in the database list because it corresponds to + // the main database which we have already described. + CursorWindow window = new CursorWindow("collectDbStats"); + try { + executeForCursorWindow("PRAGMA database_list;", null, window, 0, 0, false, null); + for (int i = 1; i < window.getNumRows(); i++) { + String name = window.getString(i, 1); + String path = window.getString(i, 2); + pageCount = 0; + pageSize = 0; + try { + pageCount = executeForLong("PRAGMA " + name + ".page_count;", null, null); + pageSize = executeForLong("PRAGMA " + name + ".page_size;", null, null); + } catch (SQLiteException ex) { + // Ignore. + } + String label = " (attached) " + name; + if (!path.isEmpty()) { + label += ": " + path; + } + dbStatsList.add(new DbStats(label, pageCount, pageSize, 0, 0, 0, 0)); + } + } catch (SQLiteException ex) { + // Ignore. + } finally { + window.close(); + } + } + + /** + * Collects statistics about database connection memory usage, in the case where the + * caller might not actually own the connection. + * + * @return The statistics object, never null. + */ + void collectDbStatsUnsafe(ArrayList<DbStats> dbStatsList) { + dbStatsList.add(getMainDbStatsUnsafe(0, 0, 0)); + } + + private DbStats getMainDbStatsUnsafe(int lookaside, long pageCount, long pageSize) { + // The prepared statement cache is thread-safe so we can access its statistics + // even if we do not own the database connection. + String label = mConfiguration.path; + if (!mIsPrimaryConnection) { + label += " (" + mConnectionId + ")"; + } + return new DbStats(label, pageCount, pageSize, lookaside, + mPreparedStatementCache.hitCount(), + mPreparedStatementCache.missCount(), + mPreparedStatementCache.size()); + } + + @Override + public String toString() { + return "SQLiteConnection: " + mConfiguration.path + " (" + mConnectionId + ")"; + } + + private PreparedStatement obtainPreparedStatement(String sql, long statementPtr, + int numParameters, int type, boolean readOnly) { + PreparedStatement statement = mPreparedStatementPool; + if (statement != null) { + mPreparedStatementPool = statement.mPoolNext; + statement.mPoolNext = null; + statement.mInCache = false; + } else { + statement = new PreparedStatement(); + } + statement.mSql = sql; + statement.mStatementPtr = statementPtr; + statement.mNumParameters = numParameters; + statement.mType = type; + statement.mReadOnly = readOnly; + return statement; + } + + private void recyclePreparedStatement(PreparedStatement statement) { + statement.mSql = null; + statement.mPoolNext = mPreparedStatementPool; + mPreparedStatementPool = statement; + } + + private static String trimSqlForDisplay(String sql) { + // Note: Creating and caching a regular expression is expensive at preload-time + // and stops compile-time initialization. This pattern is only used when + // dumping the connection, which is a rare (mainly error) case. So: + // DO NOT CACHE. + return sql.replaceAll("[\\s]*\\n+[\\s]*", " "); + } + + /** + * Holder type for a prepared statement. + * + * Although this object holds a pointer to a native statement object, it + * does not have a finalizer. This is deliberate. The {@link SQLiteConnection} + * owns the statement object and will take care of freeing it when needed. + * In particular, closing the connection requires a guarantee of deterministic + * resource disposal because all native statement objects must be freed before + * the native database object can be closed. So no finalizers here. + */ + private static final class PreparedStatement { + // Next item in pool. + public PreparedStatement mPoolNext; + + // The SQL from which the statement was prepared. + public String mSql; + + // The native sqlite3_stmt object pointer. + // Lifetime is managed explicitly by the connection. + public long mStatementPtr; + + // The number of parameters that the prepared statement has. + public int mNumParameters; + + // The statement type. + public int mType; + + // True if the statement is read-only. + public boolean mReadOnly; + + // True if the statement is in the cache. + public boolean mInCache; + + // True if the statement is in use (currently executing). + // We need this flag because due to the use of custom functions in triggers, it's + // possible for SQLite calls to be re-entrant. Consequently we need to prevent + // in use statements from being finalized until they are no longer in use. + public boolean mInUse; + } + + private final class PreparedStatementCache + extends LruCache<String, PreparedStatement> { + public PreparedStatementCache(int size) { + super(size); + } + + @Override + protected void entryRemoved(boolean evicted, String key, + PreparedStatement oldValue, PreparedStatement newValue) { + oldValue.mInCache = false; + if (!oldValue.mInUse) { + finalizePreparedStatement(oldValue); + } + } + + public void dump(Printer printer) { + printer.println(" Prepared statement cache:"); + Map<String, PreparedStatement> cache = snapshot(); + if (!cache.isEmpty()) { + int i = 0; + for (Map.Entry<String, PreparedStatement> entry : cache.entrySet()) { + PreparedStatement statement = entry.getValue(); + if (statement.mInCache) { // might be false due to a race with entryRemoved + String sql = entry.getKey(); + printer.println(" " + i + ": statementPtr=0x" + + Long.toHexString(statement.mStatementPtr) + + ", numParameters=" + statement.mNumParameters + + ", type=" + statement.mType + + ", readOnly=" + statement.mReadOnly + + ", sql=\"" + trimSqlForDisplay(sql) + "\""); + } + i += 1; + } + } else { + printer.println(" <none>"); + } + } + } + + private static final class OperationLog { + private static final int MAX_RECENT_OPERATIONS = 20; + private static final int COOKIE_GENERATION_SHIFT = 8; + private static final int COOKIE_INDEX_MASK = 0xff; + + private final Operation[] mOperations = new Operation[MAX_RECENT_OPERATIONS]; + private int mIndex; + private int mGeneration; + + public int beginOperation(String kind, String sql, Object[] bindArgs) { + synchronized (mOperations) { + final int index = (mIndex + 1) % MAX_RECENT_OPERATIONS; + Operation operation = mOperations[index]; + if (operation == null) { + operation = new Operation(); + mOperations[index] = operation; + } else { + operation.mFinished = false; + operation.mException = null; + if (operation.mBindArgs != null) { + operation.mBindArgs.clear(); + } + } + operation.mStartWallTime = System.currentTimeMillis(); + operation.mStartTime = SystemClock.uptimeMillis(); + operation.mKind = kind; + operation.mSql = sql; + if (bindArgs != null) { + if (operation.mBindArgs == null) { + operation.mBindArgs = new ArrayList<Object>(); + } else { + operation.mBindArgs.clear(); + } + for (int i = 0; i < bindArgs.length; i++) { + final Object arg = bindArgs[i]; + if (arg != null && arg instanceof byte[]) { + // Don't hold onto the real byte array longer than necessary. + operation.mBindArgs.add(EMPTY_BYTE_ARRAY); + } else { + operation.mBindArgs.add(arg); + } + } + } + operation.mCookie = newOperationCookieLocked(index); + mIndex = index; + return operation.mCookie; + } + } + + public void failOperation(int cookie, Exception ex) { + synchronized (mOperations) { + final Operation operation = getOperationLocked(cookie); + if (operation != null) { + operation.mException = ex; + } + } + } + + public void endOperation(int cookie) { + synchronized (mOperations) { + if (endOperationDeferLogLocked(cookie)) { + logOperationLocked(cookie, null); + } + } + } + + public boolean endOperationDeferLog(int cookie) { + synchronized (mOperations) { + return endOperationDeferLogLocked(cookie); + } + } + + public void logOperation(int cookie, String detail) { + synchronized (mOperations) { + logOperationLocked(cookie, detail); + } + } + + private boolean endOperationDeferLogLocked(int cookie) { + final Operation operation = getOperationLocked(cookie); + if (operation != null) { + operation.mEndTime = SystemClock.uptimeMillis(); + operation.mFinished = true; + return SQLiteDebug.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery( + operation.mEndTime - operation.mStartTime); + } + return false; + } + + private void logOperationLocked(int cookie, String detail) { + final Operation operation = getOperationLocked(cookie); + StringBuilder msg = new StringBuilder(); + operation.describe(msg, false); + if (detail != null) { + msg.append(", ").append(detail); + } + Log.d(TAG, msg.toString()); + } + + private int newOperationCookieLocked(int index) { + final int generation = mGeneration++; + return generation << COOKIE_GENERATION_SHIFT | index; + } + + private Operation getOperationLocked(int cookie) { + final int index = cookie & COOKIE_INDEX_MASK; + final Operation operation = mOperations[index]; + return operation.mCookie == cookie ? operation : null; + } + + public String describeCurrentOperation() { + synchronized (mOperations) { + final Operation operation = mOperations[mIndex]; + if (operation != null && !operation.mFinished) { + StringBuilder msg = new StringBuilder(); + operation.describe(msg, false); + return msg.toString(); + } + return null; + } + } + + public void dump(Printer printer, boolean verbose) { + synchronized (mOperations) { + printer.println(" Most recently executed operations:"); + int index = mIndex; + Operation operation = mOperations[index]; + if (operation != null) { + int n = 0; + do { + StringBuilder msg = new StringBuilder(); + msg.append(" ").append(n).append(": ["); + msg.append(operation.getFormattedStartTime()); + msg.append("] "); + operation.describe(msg, verbose); + printer.println(msg.toString()); + + if (index > 0) { + index -= 1; + } else { + index = MAX_RECENT_OPERATIONS - 1; + } + n += 1; + operation = mOperations[index]; + } while (operation != null && n < MAX_RECENT_OPERATIONS); + } else { + printer.println(" <none>"); + } + } + } + } + + private static final class Operation { + // Trim all SQL statements to 256 characters inside the trace marker. + // This limit gives plenty of context while leaving space for other + // entries in the trace buffer (and ensures atrace doesn't truncate the + // marker for us, potentially losing metadata in the process). + private static final int MAX_TRACE_METHOD_NAME_LEN = 256; + + public long mStartWallTime; // in System.currentTimeMillis() + public long mStartTime; // in SystemClock.uptimeMillis(); + public long mEndTime; // in SystemClock.uptimeMillis(); + public String mKind; + public String mSql; + public ArrayList<Object> mBindArgs; + public boolean mFinished; + public Exception mException; + public int mCookie; + + public void describe(StringBuilder msg, boolean verbose) { + msg.append(mKind); + if (mFinished) { + msg.append(" took ").append(mEndTime - mStartTime).append("ms"); + } else { + msg.append(" started ").append(System.currentTimeMillis() - mStartWallTime) + .append("ms ago"); + } + msg.append(" - ").append(getStatus()); + if (mSql != null) { + msg.append(", sql=\"").append(trimSqlForDisplay(mSql)).append("\""); + } + if (verbose && mBindArgs != null && mBindArgs.size() != 0) { + msg.append(", bindArgs=["); + final int count = mBindArgs.size(); + for (int i = 0; i < count; i++) { + final Object arg = mBindArgs.get(i); + if (i != 0) { + msg.append(", "); + } + if (arg == null) { + msg.append("null"); + } else if (arg instanceof byte[]) { + msg.append("<byte[]>"); + } else if (arg instanceof String) { + msg.append("\"").append((String)arg).append("\""); + } else { + msg.append(arg); + } + } + msg.append("]"); + } + if (mException != null) { + msg.append(", exception=\"").append(mException.getMessage()).append("\""); + } + } + + private String getStatus() { + if (!mFinished) { + return "running"; + } + return mException != null ? "failed" : "succeeded"; + } + + private String getTraceMethodName() { + String methodName = mKind + " " + mSql; + if (methodName.length() > MAX_TRACE_METHOD_NAME_LEN) + return methodName.substring(0, MAX_TRACE_METHOD_NAME_LEN); + return methodName; + } + + private String getFormattedStartTime() { + // Note: SimpleDateFormat is not thread-safe, cannot be compile-time created, and is + // relatively expensive to create during preloading. This method is only used + // when dumping a connection, which is a rare (mainly error) case. So: + // DO NOT CACHE. + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(mStartWallTime)); + } + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteConnectionPool.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteConnectionPool.java @@ -0,0 +1,1086 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import org.sqlite.database.sqlite.CloseGuard; + +import org.sqlite.database.sqlite.SQLiteDebug.DbStats; +import android.os.CancellationSignal; +import android.os.OperationCanceledException; +import android.os.SystemClock; +import android.util.Log; +import android.util.Printer; + +import java.io.Closeable; +import java.util.ArrayList; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.LockSupport; + +/** + * Maintains a pool of active SQLite database connections. + * <p> + * At any given time, a connection is either owned by the pool, or it has been + * acquired by a {@link SQLiteSession}. When the {@link SQLiteSession} is + * finished with the connection it is using, it must return the connection + * back to the pool. + * </p><p> + * The pool holds strong references to the connections it owns. However, + * it only holds <em>weak references</em> to the connections that sessions + * have acquired from it. Using weak references in the latter case ensures + * that the connection pool can detect when connections have been improperly + * abandoned so that it can create new connections to replace them if needed. + * </p><p> + * The connection pool is thread-safe (but the connections themselves are not). + * </p> + * + * <h2>Exception safety</h2> + * <p> + * This code attempts to maintain the invariant that opened connections are + * always owned. Unfortunately that means it needs to handle exceptions + * all over to ensure that broken connections get cleaned up. Most + * operations invokving SQLite can throw {@link SQLiteException} or other + * runtime exceptions. This is a bit of a pain to deal with because the compiler + * cannot help us catch missing exception handling code. + * </p><p> + * The general rule for this file: If we are making calls out to + * {@link SQLiteConnection} then we must be prepared to handle any + * runtime exceptions it might throw at us. Note that out-of-memory + * is an {@link Error}, not a {@link RuntimeException}. We don't trouble ourselves + * handling out of memory because it is hard to do anything at all sensible then + * and most likely the VM is about to crash. + * </p> + * + * @hide + */ +public final class SQLiteConnectionPool implements Closeable { + private static final String TAG = "SQLiteConnectionPool"; + + // Amount of time to wait in milliseconds before unblocking acquireConnection + // and logging a message about the connection pool being busy. + private static final long CONNECTION_POOL_BUSY_MILLIS = 30 * 1000; // 30 seconds + + private final CloseGuard mCloseGuard = CloseGuard.get(); + + private final Object mLock = new Object(); + private final AtomicBoolean mConnectionLeaked = new AtomicBoolean(); + private final SQLiteDatabaseConfiguration mConfiguration; + private int mMaxConnectionPoolSize; + private boolean mIsOpen; + private int mNextConnectionId; + + private ConnectionWaiter mConnectionWaiterPool; + private ConnectionWaiter mConnectionWaiterQueue; + + // Strong references to all available connections. + private final ArrayList<SQLiteConnection> mAvailableNonPrimaryConnections = + new ArrayList<SQLiteConnection>(); + private SQLiteConnection mAvailablePrimaryConnection; + + // Describes what should happen to an acquired connection when it is returned to the pool. + enum AcquiredConnectionStatus { + // The connection should be returned to the pool as usual. + NORMAL, + + // The connection must be reconfigured before being returned. + RECONFIGURE, + + // The connection must be closed and discarded. + DISCARD, + } + + // Weak references to all acquired connections. The associated value + // indicates whether the connection must be reconfigured before being + // returned to the available connection list or discarded. + // For example, the prepared statement cache size may have changed and + // need to be updated in preparation for the next client. + private final WeakHashMap<SQLiteConnection, AcquiredConnectionStatus> mAcquiredConnections = + new WeakHashMap<SQLiteConnection, AcquiredConnectionStatus>(); + + /** + * Connection flag: Read-only. + * <p> + * This flag indicates that the connection will only be used to + * perform read-only operations. + * </p> + */ + public static final int CONNECTION_FLAG_READ_ONLY = 1 << 0; + + /** + * Connection flag: Primary connection affinity. + * <p> + * This flag indicates that the primary connection is required. + * This flag helps support legacy applications that expect most data modifying + * operations to be serialized by locking the primary database connection. + * Setting this flag essentially implements the old "db lock" concept by preventing + * an operation from being performed until it can obtain exclusive access to + * the primary connection. + * </p> + */ + public static final int CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY = 1 << 1; + + /** + * Connection flag: Connection is being used interactively. + * <p> + * This flag indicates that the connection is needed by the UI thread. + * The connection pool can use this flag to elevate the priority + * of the database connection request. + * </p> + */ + public static final int CONNECTION_FLAG_INTERACTIVE = 1 << 2; + + private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) { + mConfiguration = new SQLiteDatabaseConfiguration(configuration); + setMaxConnectionPoolSizeLocked(); + } + + @Override + protected void finalize() throws Throwable { + try { + dispose(true); + } finally { + super.finalize(); + } + } + + /** + * Opens a connection pool for the specified database. + * + * @param configuration The database configuration. + * @return The connection pool. + * + * @throws SQLiteException if a database error occurs. + */ + public static SQLiteConnectionPool open(SQLiteDatabaseConfiguration configuration) { + if (configuration == null) { + throw new IllegalArgumentException("configuration must not be null."); + } + + // Create the pool. + SQLiteConnectionPool pool = new SQLiteConnectionPool(configuration); + pool.open(); // might throw + return pool; + } + + // Might throw + private void open() { + // Open the primary connection. + // This might throw if the database is corrupt. + mAvailablePrimaryConnection = openConnectionLocked(mConfiguration, + true /*primaryConnection*/); // might throw + + // Mark the pool as being open for business. + mIsOpen = true; + mCloseGuard.open("close"); + } + + /** + * Closes the connection pool. + * <p> + * When the connection pool is closed, it will refuse all further requests + * to acquire connections. All connections that are currently available in + * the pool are closed immediately. Any connections that are still in use + * will be closed as soon as they are returned to the pool. + * </p> + * + * @throws IllegalStateException if the pool has been closed. + */ + public void close() { + dispose(false); + } + + private void dispose(boolean finalized) { + if (mCloseGuard != null) { + if (finalized) { + mCloseGuard.warnIfOpen(); + } + mCloseGuard.close(); + } + + if (!finalized) { + // Close all connections. We don't need (or want) to do this + // when finalized because we don't know what state the connections + // themselves will be in. The finalizer is really just here for CloseGuard. + // The connections will take care of themselves when their own finalizers run. + synchronized (mLock) { + throwIfClosedLocked(); + + mIsOpen = false; + + closeAvailableConnectionsAndLogExceptionsLocked(); + + final int pendingCount = mAcquiredConnections.size(); + if (pendingCount != 0) { + Log.i(TAG, "The connection pool for " + mConfiguration.label + + " has been closed but there are still " + + pendingCount + " connections in use. They will be closed " + + "as they are released back to the pool."); + } + + wakeConnectionWaitersLocked(); + } + } + } + + /** + * Reconfigures the database configuration of the connection pool and all of its + * connections. + * <p> + * Configuration changes are propagated down to connections immediately if + * they are available or as soon as they are released. This includes changes + * that affect the size of the pool. + * </p> + * + * @param configuration The new configuration. + * + * @throws IllegalStateException if the pool has been closed. + */ + public void reconfigure(SQLiteDatabaseConfiguration configuration) { + if (configuration == null) { + throw new IllegalArgumentException("configuration must not be null."); + } + + synchronized (mLock) { + throwIfClosedLocked(); + + boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags) + & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0; + if (walModeChanged) { + // WAL mode can only be changed if there are no acquired connections + // because we need to close all but the primary connection first. + if (!mAcquiredConnections.isEmpty()) { + throw new IllegalStateException("Write Ahead Logging (WAL) mode cannot " + + "be enabled or disabled while there are transactions in " + + "progress. Finish all transactions and release all active " + + "database connections first."); + } + + // Close all non-primary connections. This should happen immediately + // because none of them are in use. + closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked(); + assert mAvailableNonPrimaryConnections.isEmpty(); + } + + boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled + != mConfiguration.foreignKeyConstraintsEnabled; + if (foreignKeyModeChanged) { + // Foreign key constraints can only be changed if there are no transactions + // in progress. To make this clear, we throw an exception if there are + // any acquired connections. + if (!mAcquiredConnections.isEmpty()) { + throw new IllegalStateException("Foreign Key Constraints cannot " + + "be enabled or disabled while there are transactions in " + + "progress. Finish all transactions and release all active " + + "database connections first."); + } + } + + if (mConfiguration.openFlags != configuration.openFlags) { + // If we are changing open flags and WAL mode at the same time, then + // we have no choice but to close the primary connection beforehand + // because there can only be one connection open when we change WAL mode. + if (walModeChanged) { + closeAvailableConnectionsAndLogExceptionsLocked(); + } + + // Try to reopen the primary connection using the new open flags then + // close and discard all existing connections. + // This might throw if the database is corrupt or cannot be opened in + // the new mode in which case existing connections will remain untouched. + SQLiteConnection newPrimaryConnection = openConnectionLocked(configuration, + true /*primaryConnection*/); // might throw + + closeAvailableConnectionsAndLogExceptionsLocked(); + discardAcquiredConnectionsLocked(); + + mAvailablePrimaryConnection = newPrimaryConnection; + mConfiguration.updateParametersFrom(configuration); + setMaxConnectionPoolSizeLocked(); + } else { + // Reconfigure the database connections in place. + mConfiguration.updateParametersFrom(configuration); + setMaxConnectionPoolSizeLocked(); + + closeExcessConnectionsAndLogExceptionsLocked(); + reconfigureAllConnectionsLocked(); + } + + wakeConnectionWaitersLocked(); + } + } + + /** + * Acquires a connection from the pool. + * <p> + * The caller must call {@link #releaseConnection} to release the connection + * back to the pool when it is finished. Failure to do so will result + * in much unpleasantness. + * </p> + * + * @param sql If not null, try to find a connection that already has + * the specified SQL statement in its prepared statement cache. + * @param connectionFlags The connection request flags. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The connection that was acquired, never null. + * + * @throws IllegalStateException if the pool has been closed. + * @throws SQLiteException if a database error occurs. + * @throws OperationCanceledException if the operation was canceled. + */ + public SQLiteConnection acquireConnection(String sql, int connectionFlags, + CancellationSignal cancellationSignal) { + return waitForConnection(sql, connectionFlags, cancellationSignal); + } + + /** + * Releases a connection back to the pool. + * <p> + * It is ok to call this method after the pool has closed, to release + * connections that were still in use at the time of closure. + * </p> + * + * @param connection The connection to release. Must not be null. + * + * @throws IllegalStateException if the connection was not acquired + * from this pool or if it has already been released. + */ + public void releaseConnection(SQLiteConnection connection) { + synchronized (mLock) { + AcquiredConnectionStatus status = mAcquiredConnections.remove(connection); + if (status == null) { + throw new IllegalStateException("Cannot perform this operation " + + "because the specified connection was not acquired " + + "from this pool or has already been released."); + } + + if (!mIsOpen) { + closeConnectionAndLogExceptionsLocked(connection); + } else if (connection.isPrimaryConnection()) { + if (recycleConnectionLocked(connection, status)) { + assert mAvailablePrimaryConnection == null; + mAvailablePrimaryConnection = connection; + } + wakeConnectionWaitersLocked(); + } else if (mAvailableNonPrimaryConnections.size() >= mMaxConnectionPoolSize - 1) { + closeConnectionAndLogExceptionsLocked(connection); + } else { + if (recycleConnectionLocked(connection, status)) { + mAvailableNonPrimaryConnections.add(connection); + } + wakeConnectionWaitersLocked(); + } + } + } + + // Can't throw. + private boolean recycleConnectionLocked(SQLiteConnection connection, + AcquiredConnectionStatus status) { + if (status == AcquiredConnectionStatus.RECONFIGURE) { + try { + connection.reconfigure(mConfiguration); // might throw + } catch (RuntimeException ex) { + Log.e(TAG, "Failed to reconfigure released connection, closing it: " + + connection, ex); + status = AcquiredConnectionStatus.DISCARD; + } + } + if (status == AcquiredConnectionStatus.DISCARD) { + closeConnectionAndLogExceptionsLocked(connection); + return false; + } + return true; + } + + /** + * Returns true if the session should yield the connection due to + * contention over available database connections. + * + * @param connection The connection owned by the session. + * @param connectionFlags The connection request flags. + * @return True if the session should yield its connection. + * + * @throws IllegalStateException if the connection was not acquired + * from this pool or if it has already been released. + */ + public boolean shouldYieldConnection(SQLiteConnection connection, int connectionFlags) { + synchronized (mLock) { + if (!mAcquiredConnections.containsKey(connection)) { + throw new IllegalStateException("Cannot perform this operation " + + "because the specified connection was not acquired " + + "from this pool or has already been released."); + } + + if (!mIsOpen) { + return false; + } + + return isSessionBlockingImportantConnectionWaitersLocked( + connection.isPrimaryConnection(), connectionFlags); + } + } + + /** + * Collects statistics about database connection memory usage. + * + * @param dbStatsList The list to populate. + */ + public void collectDbStats(ArrayList<DbStats> dbStatsList) { + synchronized (mLock) { + if (mAvailablePrimaryConnection != null) { + mAvailablePrimaryConnection.collectDbStats(dbStatsList); + } + + for (SQLiteConnection connection : mAvailableNonPrimaryConnections) { + connection.collectDbStats(dbStatsList); + } + + for (SQLiteConnection connection : mAcquiredConnections.keySet()) { + connection.collectDbStatsUnsafe(dbStatsList); + } + } + } + + // Might throw. + private SQLiteConnection openConnectionLocked(SQLiteDatabaseConfiguration configuration, + boolean primaryConnection) { + final int connectionId = mNextConnectionId++; + return SQLiteConnection.open(this, configuration, + connectionId, primaryConnection); // might throw + } + + void onConnectionLeaked() { + // This code is running inside of the SQLiteConnection finalizer. + // + // We don't know whether it is just the connection that has been finalized (and leaked) + // or whether the connection pool has also been or is about to be finalized. + // Consequently, it would be a bad idea to try to grab any locks or to + // do any significant work here. So we do the simplest possible thing and + // set a flag. waitForConnection() periodically checks this flag (when it + // times out) so that it can recover from leaked connections and wake + // itself or other threads up if necessary. + // + // You might still wonder why we don't try to do more to wake up the waiters + // immediately. First, as explained above, it would be hard to do safely + // unless we started an extra Thread to function as a reference queue. Second, + // this is never supposed to happen in normal operation. Third, there is no + // guarantee that the GC will actually detect the leak in a timely manner so + // it's not all that important that we recover from the leak in a timely manner + // either. Fourth, if a badly behaved application finds itself hung waiting for + // several seconds while waiting for a leaked connection to be detected and recreated, + // then perhaps its authors will have added incentive to fix the problem! + + Log.w(TAG, "A SQLiteConnection object for database '" + + mConfiguration.label + "' was leaked! Please fix your application " + + "to end transactions in progress properly and to close the database " + + "when it is no longer needed."); + + mConnectionLeaked.set(true); + } + + // Can't throw. + private void closeAvailableConnectionsAndLogExceptionsLocked() { + closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked(); + + if (mAvailablePrimaryConnection != null) { + closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection); + mAvailablePrimaryConnection = null; + } + } + + // Can't throw. + private void closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked() { + final int count = mAvailableNonPrimaryConnections.size(); + for (int i = 0; i < count; i++) { + closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i)); + } + mAvailableNonPrimaryConnections.clear(); + } + + // Can't throw. + private void closeExcessConnectionsAndLogExceptionsLocked() { + int availableCount = mAvailableNonPrimaryConnections.size(); + while (availableCount-- > mMaxConnectionPoolSize - 1) { + SQLiteConnection connection = + mAvailableNonPrimaryConnections.remove(availableCount); + closeConnectionAndLogExceptionsLocked(connection); + } + } + + // Can't throw. + private void closeConnectionAndLogExceptionsLocked(SQLiteConnection connection) { + try { + connection.close(); // might throw + } catch (RuntimeException ex) { + Log.e(TAG, "Failed to close connection, its fate is now in the hands " + + "of the merciful GC: " + connection, ex); + } + } + + // Can't throw. + private void discardAcquiredConnectionsLocked() { + markAcquiredConnectionsLocked(AcquiredConnectionStatus.DISCARD); + } + + // Can't throw. + private void reconfigureAllConnectionsLocked() { + if (mAvailablePrimaryConnection != null) { + try { + mAvailablePrimaryConnection.reconfigure(mConfiguration); // might throw + } catch (RuntimeException ex) { + Log.e(TAG, "Failed to reconfigure available primary connection, closing it: " + + mAvailablePrimaryConnection, ex); + closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection); + mAvailablePrimaryConnection = null; + } + } + + int count = mAvailableNonPrimaryConnections.size(); + for (int i = 0; i < count; i++) { + final SQLiteConnection connection = mAvailableNonPrimaryConnections.get(i); + try { + connection.reconfigure(mConfiguration); // might throw + } catch (RuntimeException ex) { + Log.e(TAG, "Failed to reconfigure available non-primary connection, closing it: " + + connection, ex); + closeConnectionAndLogExceptionsLocked(connection); + mAvailableNonPrimaryConnections.remove(i--); + count -= 1; + } + } + + markAcquiredConnectionsLocked(AcquiredConnectionStatus.RECONFIGURE); + } + + // Can't throw. + private void markAcquiredConnectionsLocked(AcquiredConnectionStatus status) { + if (!mAcquiredConnections.isEmpty()) { + ArrayList<SQLiteConnection> keysToUpdate = new ArrayList<SQLiteConnection>( + mAcquiredConnections.size()); + for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry + : mAcquiredConnections.entrySet()) { + AcquiredConnectionStatus oldStatus = entry.getValue(); + if (status != oldStatus + && oldStatus != AcquiredConnectionStatus.DISCARD) { + keysToUpdate.add(entry.getKey()); + } + } + final int updateCount = keysToUpdate.size(); + for (int i = 0; i < updateCount; i++) { + mAcquiredConnections.put(keysToUpdate.get(i), status); + } + } + } + + // Might throw. + private SQLiteConnection waitForConnection(String sql, int connectionFlags, + CancellationSignal cancellationSignal) { + final boolean wantPrimaryConnection = + (connectionFlags & CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY) != 0; + + final ConnectionWaiter waiter; + final int nonce; + synchronized (mLock) { + throwIfClosedLocked(); + + // Abort if canceled. + if (cancellationSignal != null) { + cancellationSignal.throwIfCanceled(); + } + + // Try to acquire a connection. + SQLiteConnection connection = null; + if (!wantPrimaryConnection) { + connection = tryAcquireNonPrimaryConnectionLocked( + sql, connectionFlags); // might throw + } + if (connection == null) { + connection = tryAcquirePrimaryConnectionLocked(connectionFlags); // might throw + } + if (connection != null) { + return connection; + } + + // No connections available. Enqueue a waiter in priority order. + final int priority = getPriority(connectionFlags); + final long startTime = SystemClock.uptimeMillis(); + waiter = obtainConnectionWaiterLocked(Thread.currentThread(), startTime, + priority, wantPrimaryConnection, sql, connectionFlags); + ConnectionWaiter predecessor = null; + ConnectionWaiter successor = mConnectionWaiterQueue; + while (successor != null) { + if (priority > successor.mPriority) { + waiter.mNext = successor; + break; + } + predecessor = successor; + successor = successor.mNext; + } + if (predecessor != null) { + predecessor.mNext = waiter; + } else { + mConnectionWaiterQueue = waiter; + } + + nonce = waiter.mNonce; + } + + // Set up the cancellation listener. + if (cancellationSignal != null) { + cancellationSignal.setOnCancelListener(new CancellationSignal.OnCancelListener() { + @Override + public void onCancel() { + synchronized (mLock) { + if (waiter.mNonce == nonce) { + cancelConnectionWaiterLocked(waiter); + } + } + } + }); + } + try { + // Park the thread until a connection is assigned or the pool is closed. + // Rethrow an exception from the wait, if we got one. + long busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS; + long nextBusyTimeoutTime = waiter.mStartTime + busyTimeoutMillis; + for (;;) { + // Detect and recover from connection leaks. + if (mConnectionLeaked.compareAndSet(true, false)) { + synchronized (mLock) { + wakeConnectionWaitersLocked(); + } + } + + // Wait to be unparked (may already have happened), a timeout, or interruption. + LockSupport.parkNanos(this, busyTimeoutMillis * 1000000L); + + // Clear the interrupted flag, just in case. + Thread.interrupted(); + + // Check whether we are done waiting yet. + synchronized (mLock) { + throwIfClosedLocked(); + + final SQLiteConnection connection = waiter.mAssignedConnection; + final RuntimeException ex = waiter.mException; + if (connection != null || ex != null) { + recycleConnectionWaiterLocked(waiter); + if (connection != null) { + return connection; + } + throw ex; // rethrow! + } + + final long now = SystemClock.uptimeMillis(); + if (now < nextBusyTimeoutTime) { + busyTimeoutMillis = now - nextBusyTimeoutTime; + } else { + logConnectionPoolBusyLocked(now - waiter.mStartTime, connectionFlags); + busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS; + nextBusyTimeoutTime = now + busyTimeoutMillis; + } + } + } + } finally { + // Remove the cancellation listener. + if (cancellationSignal != null) { + cancellationSignal.setOnCancelListener(null); + } + } + } + + // Can't throw. + private void cancelConnectionWaiterLocked(ConnectionWaiter waiter) { + if (waiter.mAssignedConnection != null || waiter.mException != null) { + // Waiter is done waiting but has not woken up yet. + return; + } + + // Waiter must still be waiting. Dequeue it. + ConnectionWaiter predecessor = null; + ConnectionWaiter current = mConnectionWaiterQueue; + while (current != waiter) { + assert current != null; + predecessor = current; + current = current.mNext; + } + if (predecessor != null) { + predecessor.mNext = waiter.mNext; + } else { + mConnectionWaiterQueue = waiter.mNext; + } + + // Send the waiter an exception and unpark it. + waiter.mException = new OperationCanceledException(); + LockSupport.unpark(waiter.mThread); + + // Check whether removing this waiter will enable other waiters to make progress. + wakeConnectionWaitersLocked(); + } + + // Can't throw. + private void logConnectionPoolBusyLocked(long waitMillis, int connectionFlags) { + final Thread thread = Thread.currentThread(); + StringBuilder msg = new StringBuilder(); + msg.append("The connection pool for database '").append(mConfiguration.label); + msg.append("' has been unable to grant a connection to thread "); + msg.append(thread.getId()).append(" (").append(thread.getName()).append(") "); + msg.append("with flags 0x").append(Integer.toHexString(connectionFlags)); + msg.append(" for ").append(waitMillis * 0.001f).append(" seconds.\n"); + + ArrayList<String> requests = new ArrayList<String>(); + int activeConnections = 0; + int idleConnections = 0; + if (!mAcquiredConnections.isEmpty()) { + for (SQLiteConnection connection : mAcquiredConnections.keySet()) { + String description = connection.describeCurrentOperationUnsafe(); + if (description != null) { + requests.add(description); + activeConnections += 1; + } else { + idleConnections += 1; + } + } + } + int availableConnections = mAvailableNonPrimaryConnections.size(); + if (mAvailablePrimaryConnection != null) { + availableConnections += 1; + } + + msg.append("Connections: ").append(activeConnections).append(" active, "); + msg.append(idleConnections).append(" idle, "); + msg.append(availableConnections).append(" available.\n"); + + if (!requests.isEmpty()) { + msg.append("\nRequests in progress:\n"); + for (String request : requests) { + msg.append(" ").append(request).append("\n"); + } + } + + Log.w(TAG, msg.toString()); + } + + // Can't throw. + private void wakeConnectionWaitersLocked() { + // Unpark all waiters that have requests that we can fulfill. + // This method is designed to not throw runtime exceptions, although we might send + // a waiter an exception for it to rethrow. + ConnectionWaiter predecessor = null; + ConnectionWaiter waiter = mConnectionWaiterQueue; + boolean primaryConnectionNotAvailable = false; + boolean nonPrimaryConnectionNotAvailable = false; + while (waiter != null) { + boolean unpark = false; + if (!mIsOpen) { + unpark = true; + } else { + try { + SQLiteConnection connection = null; + if (!waiter.mWantPrimaryConnection && !nonPrimaryConnectionNotAvailable) { + connection = tryAcquireNonPrimaryConnectionLocked( + waiter.mSql, waiter.mConnectionFlags); // might throw + if (connection == null) { + nonPrimaryConnectionNotAvailable = true; + } + } + if (connection == null && !primaryConnectionNotAvailable) { + connection = tryAcquirePrimaryConnectionLocked( + waiter.mConnectionFlags); // might throw + if (connection == null) { + primaryConnectionNotAvailable = true; + } + } + if (connection != null) { + waiter.mAssignedConnection = connection; + unpark = true; + } else if (nonPrimaryConnectionNotAvailable && primaryConnectionNotAvailable) { + // There are no connections available and the pool is still open. + // We cannot fulfill any more connection requests, so stop here. + break; + } + } catch (RuntimeException ex) { + // Let the waiter handle the exception from acquiring a connection. + waiter.mException = ex; + unpark = true; + } + } + + final ConnectionWaiter successor = waiter.mNext; + if (unpark) { + if (predecessor != null) { + predecessor.mNext = successor; + } else { + mConnectionWaiterQueue = successor; + } + waiter.mNext = null; + + LockSupport.unpark(waiter.mThread); + } else { + predecessor = waiter; + } + waiter = successor; + } + } + + // Might throw. + private SQLiteConnection tryAcquirePrimaryConnectionLocked(int connectionFlags) { + // If the primary connection is available, acquire it now. + SQLiteConnection connection = mAvailablePrimaryConnection; + if (connection != null) { + mAvailablePrimaryConnection = null; + finishAcquireConnectionLocked(connection, connectionFlags); // might throw + return connection; + } + + // Make sure that the primary connection actually exists and has just been acquired. + for (SQLiteConnection acquiredConnection : mAcquiredConnections.keySet()) { + if (acquiredConnection.isPrimaryConnection()) { + return null; + } + } + + // Uhoh. No primary connection! Either this is the first time we asked + // for it, or maybe it leaked? + connection = openConnectionLocked(mConfiguration, + true /*primaryConnection*/); // might throw + finishAcquireConnectionLocked(connection, connectionFlags); // might throw + return connection; + } + + // Might throw. + private SQLiteConnection tryAcquireNonPrimaryConnectionLocked( + String sql, int connectionFlags) { + // Try to acquire the next connection in the queue. + SQLiteConnection connection; + final int availableCount = mAvailableNonPrimaryConnections.size(); + if (availableCount > 1 && sql != null) { + // If we have a choice, then prefer a connection that has the + // prepared statement in its cache. + for (int i = 0; i < availableCount; i++) { + connection = mAvailableNonPrimaryConnections.get(i); + if (connection.isPreparedStatementInCache(sql)) { + mAvailableNonPrimaryConnections.remove(i); + finishAcquireConnectionLocked(connection, connectionFlags); // might throw + return connection; + } + } + } + if (availableCount > 0) { + // Otherwise, just grab the next one. + connection = mAvailableNonPrimaryConnections.remove(availableCount - 1); + finishAcquireConnectionLocked(connection, connectionFlags); // might throw + return connection; + } + + // Expand the pool if needed. + int openConnections = mAcquiredConnections.size(); + if (mAvailablePrimaryConnection != null) { + openConnections += 1; + } + if (openConnections >= mMaxConnectionPoolSize) { + return null; + } + connection = openConnectionLocked(mConfiguration, + false /*primaryConnection*/); // might throw + finishAcquireConnectionLocked(connection, connectionFlags); // might throw + return connection; + } + + // Might throw. + private void finishAcquireConnectionLocked(SQLiteConnection connection, int connectionFlags) { + try { + final boolean readOnly = (connectionFlags & CONNECTION_FLAG_READ_ONLY) != 0; + connection.setOnlyAllowReadOnlyOperations(readOnly); + + mAcquiredConnections.put(connection, AcquiredConnectionStatus.NORMAL); + } catch (RuntimeException ex) { + Log.e(TAG, "Failed to prepare acquired connection for session, closing it: " + + connection +", connectionFlags=" + connectionFlags); + closeConnectionAndLogExceptionsLocked(connection); + throw ex; // rethrow! + } + } + + private boolean isSessionBlockingImportantConnectionWaitersLocked( + boolean holdingPrimaryConnection, int connectionFlags) { + ConnectionWaiter waiter = mConnectionWaiterQueue; + if (waiter != null) { + final int priority = getPriority(connectionFlags); + do { + // Only worry about blocked connections that have same or lower priority. + if (priority > waiter.mPriority) { + break; + } + + // If we are holding the primary connection then we are blocking the waiter. + // Likewise, if we are holding a non-primary connection and the waiter + // would accept a non-primary connection, then we are blocking the waier. + if (holdingPrimaryConnection || !waiter.mWantPrimaryConnection) { + return true; + } + + waiter = waiter.mNext; + } while (waiter != null); + } + return false; + } + + private static int getPriority(int connectionFlags) { + return (connectionFlags & CONNECTION_FLAG_INTERACTIVE) != 0 ? 1 : 0; + } + + private void setMaxConnectionPoolSizeLocked() { + if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) { + mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize(); + } else { + // TODO: We don't actually need to restrict the connection pool size to 1 + // for non-WAL databases. There might be reasons to use connection pooling + // with other journal modes. For now, enabling connection pooling and + // using WAL are the same thing in the API. + mMaxConnectionPoolSize = 1; + } + } + + private void throwIfClosedLocked() { + if (!mIsOpen) { + throw new IllegalStateException("Cannot perform this operation " + + "because the connection pool has been closed."); + } + } + + private ConnectionWaiter obtainConnectionWaiterLocked(Thread thread, long startTime, + int priority, boolean wantPrimaryConnection, String sql, int connectionFlags) { + ConnectionWaiter waiter = mConnectionWaiterPool; + if (waiter != null) { + mConnectionWaiterPool = waiter.mNext; + waiter.mNext = null; + } else { + waiter = new ConnectionWaiter(); + } + waiter.mThread = thread; + waiter.mStartTime = startTime; + waiter.mPriority = priority; + waiter.mWantPrimaryConnection = wantPrimaryConnection; + waiter.mSql = sql; + waiter.mConnectionFlags = connectionFlags; + return waiter; + } + + private void recycleConnectionWaiterLocked(ConnectionWaiter waiter) { + waiter.mNext = mConnectionWaiterPool; + waiter.mThread = null; + waiter.mSql = null; + waiter.mAssignedConnection = null; + waiter.mException = null; + waiter.mNonce += 1; + mConnectionWaiterPool = waiter; + } + + public void enableLocalizedCollators() { + synchronized (mLock) { + if( !mAcquiredConnections.isEmpty() || mAvailablePrimaryConnection==null ) { + throw new IllegalStateException( + "Cannot enable localized collators while database is in use" + ); + } + mAvailablePrimaryConnection.enableLocalizedCollators(); + } + } + + /** + * Dumps debugging information about this connection pool. + * + * @param printer The printer to receive the dump, not null. + * @param verbose True to dump more verbose information. + */ + public void dump(Printer printer, boolean verbose) { + Printer indentedPrinter = printer; + synchronized (mLock) { + printer.println("Connection pool for " + mConfiguration.path + ":"); + printer.println(" Open: " + mIsOpen); + printer.println(" Max connections: " + mMaxConnectionPoolSize); + + printer.println(" Available primary connection:"); + if (mAvailablePrimaryConnection != null) { + mAvailablePrimaryConnection.dump(indentedPrinter, verbose); + } else { + indentedPrinter.println("<none>"); + } + + printer.println(" Available non-primary connections:"); + if (!mAvailableNonPrimaryConnections.isEmpty()) { + final int count = mAvailableNonPrimaryConnections.size(); + for (int i = 0; i < count; i++) { + mAvailableNonPrimaryConnections.get(i).dump(indentedPrinter, verbose); + } + } else { + indentedPrinter.println("<none>"); + } + + printer.println(" Acquired connections:"); + if (!mAcquiredConnections.isEmpty()) { + for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry : + mAcquiredConnections.entrySet()) { + final SQLiteConnection connection = entry.getKey(); + connection.dumpUnsafe(indentedPrinter, verbose); + indentedPrinter.println(" Status: " + entry.getValue()); + } + } else { + indentedPrinter.println("<none>"); + } + + printer.println(" Connection waiters:"); + if (mConnectionWaiterQueue != null) { + int i = 0; + final long now = SystemClock.uptimeMillis(); + for (ConnectionWaiter waiter = mConnectionWaiterQueue; waiter != null; + waiter = waiter.mNext, i++) { + indentedPrinter.println(i + ": waited for " + + ((now - waiter.mStartTime) * 0.001f) + + " ms - thread=" + waiter.mThread + + ", priority=" + waiter.mPriority + + ", sql='" + waiter.mSql + "'"); + } + } else { + indentedPrinter.println("<none>"); + } + } + } + + @Override + public String toString() { + return "SQLiteConnectionPool: " + mConfiguration.path; + } + + private static final class ConnectionWaiter { + public ConnectionWaiter mNext; + public Thread mThread; + public long mStartTime; + public int mPriority; + public boolean mWantPrimaryConnection; + public String mSql; + public int mConnectionFlags; + public SQLiteConnection mAssignedConnection; + public RuntimeException mException; + public int mNonce; + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteConstraintException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteConstraintException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * An exception that indicates that an integrity constraint was violated. + */ +public class SQLiteConstraintException extends SQLiteException { + public SQLiteConstraintException() {} + + public SQLiteConstraintException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCursor.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCursor.java @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.database.AbstractWindowedCursor; +import android.database.CursorWindow; +import org.sqlite.database.DatabaseUtils; + +import android.os.StrictMode; +import android.util.Log; + +import java.util.HashMap; +import java.util.Map; + +/** + * A Cursor implementation that exposes results from a query on a + * {@link SQLiteDatabase}. + * + * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple + * threads should perform its own synchronization when using the SQLiteCursor. + */ +public class SQLiteCursor extends AbstractWindowedCursor { + static final String TAG = "SQLiteCursor"; + static final int NO_COUNT = -1; + + /** The name of the table to edit */ + private final String mEditTable; + + /** The names of the columns in the rows */ + private final String[] mColumns; + + /** The query object for the cursor */ + private final SQLiteQuery mQuery; + + /** The compiled query this cursor came from */ + private final SQLiteCursorDriver mDriver; + + /** The number of rows in the cursor */ + private int mCount = NO_COUNT; + + /** The number of rows that can fit in the cursor window, 0 if unknown */ + private int mCursorWindowCapacity; + + /** A mapping of column names to column indices, to speed up lookups */ + private Map<String, Integer> mColumnNameMap; + + /** + * Execute a query and provide access to its result set through a Cursor + * interface. For a query such as: {@code SELECT name, birth, phone FROM + * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth, + * phone) would be in the projection argument and everything from + * {@code FROM} onward would be in the params argument. + * + * @param db a reference to a Database object that is already constructed + * and opened. This param is not used any longer + * @param editTable the name of the table used for this query + * @param query the rest of the query terms + * cursor is finalized + * @deprecated use {@link #SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)} instead + */ + @Deprecated + public SQLiteCursor(SQLiteDatabase db, SQLiteCursorDriver driver, + String editTable, SQLiteQuery query) { + this(driver, editTable, query); + } + + /** + * Execute a query and provide access to its result set through a Cursor + * interface. For a query such as: {@code SELECT name, birth, phone FROM + * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth, + * phone) would be in the projection argument and everything from + * {@code FROM} onward would be in the params argument. + * + * @param editTable the name of the table used for this query + * @param query the {@link SQLiteQuery} object associated with this cursor object. + */ + public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) { + if (query == null) { + throw new IllegalArgumentException("query object cannot be null"); + } + mDriver = driver; + mEditTable = editTable; + mColumnNameMap = null; + mQuery = query; + + mColumns = query.getColumnNames(); + } + + /** + * Get the database that this cursor is associated with. + * @return the SQLiteDatabase that this cursor is associated with. + */ + public SQLiteDatabase getDatabase() { + return mQuery.getDatabase(); + } + + @Override + public boolean onMove(int oldPosition, int newPosition) { + // Make sure the row at newPosition is present in the window + if (mWindow == null || newPosition < mWindow.getStartPosition() || + newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) { + fillWindow(newPosition); + } + + return true; + } + + @Override + public int getCount() { + if (mCount == NO_COUNT) { + fillWindow(0); + } + return mCount; + } + + /* + ** The AbstractWindowClass contains protected methods clearOrCreateWindow() and + ** closeWindow(), which are used by the android.database.sqlite.* version of this + ** class. But, since they are marked with "@hide", the following replacement + ** versions are required. + */ + private void awc_clearOrCreateWindow(String name){ + CursorWindow win = getWindow(); + if( win==null ){ + win = new CursorWindow(name); + setWindow(win); + }else{ + win.clear(); + } + } + private void awc_closeWindow(){ + setWindow(null); + } + + private void fillWindow(int requiredPos) { + awc_clearOrCreateWindow(getDatabase().getPath()); + + try { + if (mCount == NO_COUNT) { + int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0); + mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true); + mCursorWindowCapacity = mWindow.getNumRows(); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "received count(*) from native_fill_window: " + mCount); + } + } else { + int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, + mCursorWindowCapacity); + mQuery.fillWindow(mWindow, startPos, requiredPos, false); + } + } catch (RuntimeException ex) { + // Close the cursor window if the query failed and therefore will + // not produce any results. This helps to avoid accidentally leaking + // the cursor window if the client does not correctly handle exceptions + // and fails to close the cursor. + awc_closeWindow(); + throw ex; + } + } + + @Override + public int getColumnIndex(String columnName) { + // Create mColumnNameMap on demand + if (mColumnNameMap == null) { + String[] columns = mColumns; + int columnCount = columns.length; + HashMap<String, Integer> map = new HashMap<String, Integer>(columnCount, 1); + for (int i = 0; i < columnCount; i++) { + map.put(columns[i], i); + } + mColumnNameMap = map; + } + + // Hack according to bug 903852 + final int periodIndex = columnName.lastIndexOf('.'); + if (periodIndex != -1) { + Exception e = new Exception(); + Log.e(TAG, "requesting column name with table name -- " + columnName, e); + columnName = columnName.substring(periodIndex + 1); + } + + Integer i = mColumnNameMap.get(columnName); + if (i != null) { + return i.intValue(); + } else { + return -1; + } + } + + @Override + public String[] getColumnNames() { + return mColumns; + } + + @Override + public void deactivate() { + super.deactivate(); + mDriver.cursorDeactivated(); + } + + @Override + public void close() { + super.close(); + synchronized (this) { + mQuery.close(); + mDriver.cursorClosed(); + } + } + + @Override + public boolean requery() { + if (isClosed()) { + return false; + } + + synchronized (this) { + if (!mQuery.getDatabase().isOpen()) { + return false; + } + + if (mWindow != null) { + mWindow.clear(); + } + mPos = -1; + mCount = NO_COUNT; + + mDriver.cursorRequeried(this); + } + + try { + return super.requery(); + } catch (IllegalStateException e) { + // for backwards compatibility, just return false + Log.w(TAG, "requery() failed " + e.getMessage(), e); + return false; + } + } + + @Override + public void setWindow(CursorWindow window) { + super.setWindow(window); + mCount = NO_COUNT; + } + + /** + * Changes the selection arguments. The new values take effect after a call to requery(). + */ + public void setSelectionArguments(String[] selectionArgs) { + mDriver.setBindArguments(selectionArgs); + } + + /** + * Release the native resources, if they haven't been released yet. + */ + @Override + protected void finalize() { + try { + // if the cursor hasn't been closed yet, close it first + if (mWindow != null) { + close(); + } + } finally { + super.finalize(); + } + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCursorDriver.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCursorDriver.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.database.Cursor; +import org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory; + +/** + * A driver for SQLiteCursors that is used to create them and gets notified + * by the cursors it creates on significant events in their lifetimes. + */ +public interface SQLiteCursorDriver { + /** + * Executes the query returning a Cursor over the result set. + * + * @param factory The CursorFactory to use when creating the Cursors, or + * null if standard SQLiteCursors should be returned. + * @return a Cursor over the result set + */ + Cursor query(CursorFactory factory, String[] bindArgs); + + /** + * Called by a SQLiteCursor when it is released. + */ + void cursorDeactivated(); + + /** + * Called by a SQLiteCursor when it is requeried. + */ + void cursorRequeried(Cursor cursor); + + /** + * Called by a SQLiteCursor when it it closed to destroy this object as well. + */ + void cursorClosed(); + + /** + * Set new bind arguments. These will take effect in cursorRequeried(). + * @param bindArgs the new arguments + */ + public void setBindArguments(String[] bindArgs); +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCustomFunction.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteCustomFunction.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * Describes a custom SQL function. + * + * @hide + */ +public final class SQLiteCustomFunction { + public final String name; + public final int numArgs; + public final SQLiteDatabase.CustomFunction callback; + + /** + * Create custom function. + * + * @param name The name of the sqlite3 function. + * @param numArgs The number of arguments for the function, or -1 to + * support any number of arguments. + * @param callback The callback to invoke when the function is executed. + */ + public SQLiteCustomFunction(String name, int numArgs, + SQLiteDatabase.CustomFunction callback) { + if (name == null) { + throw new IllegalArgumentException("name must not be null."); + } + + this.name = name; + this.numArgs = numArgs; + this.callback = callback; + } + + // Called from native. + @SuppressWarnings("unused") + private void dispatchCallback(String[] args) { + callback.callback(args); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabase.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabase.java @@ -0,0 +1,2223 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.content.ContentValues; +import android.database.Cursor; +import org.sqlite.database.DatabaseErrorHandler; +import org.sqlite.database.DatabaseUtils; +import org.sqlite.database.DefaultDatabaseErrorHandler; +import org.sqlite.database.SQLException; +import org.sqlite.database.sqlite.SQLiteDebug.DbStats; +import android.os.CancellationSignal; +import android.os.Looper; +import android.os.OperationCanceledException; +import android.text.TextUtils; +import android.util.EventLog; +import android.util.Log; +import android.util.Pair; +import android.util.Printer; + +import org.sqlite.database.sqlite.CloseGuard; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * Exposes methods to manage a SQLite database. + * + * <p> + * SQLiteDatabase has methods to create, delete, execute SQL commands, and + * perform other common database management tasks. + * </p><p> + * See the Notepad sample application in the SDK for an example of creating + * and managing a database. + * </p><p> + * Database names must be unique within an application, not across all applications. + * </p> + * + * <h3>Localized Collation - ORDER BY</h3> + * <p> + * In addition to SQLite's default <code>BINARY</code> collator, Android supplies + * two more, <code>LOCALIZED</code>, which changes with the system's current locale, + * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored + * to the current locale. + * </p> + */ +public final class SQLiteDatabase extends SQLiteClosable { + private static final String TAG = "SQLiteDatabase"; + + private static final int EVENT_DB_CORRUPT = 75004; + + // Stores reference to all databases opened in the current process. + // (The referent Object is not used at this time.) + // INVARIANT: Guarded by sActiveDatabases. + private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases = + new WeakHashMap<SQLiteDatabase, Object>(); + + // Thread-local for database sessions that belong to this database. + // Each thread has its own database session. + // INVARIANT: Immutable. + private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() { + @Override + protected SQLiteSession initialValue() { + return createSession(); + } + }; + + // The optional factory to use when creating new Cursors. May be null. + // INVARIANT: Immutable. + private final CursorFactory mCursorFactory; + + // Error handler to be used when SQLite returns corruption errors. + // INVARIANT: Immutable. + private final DatabaseErrorHandler mErrorHandler; + + // Shared database state lock. + // This lock guards all of the shared state of the database, such as its + // configuration, whether it is open or closed, and so on. This lock should + // be held for as little time as possible. + // + // The lock MUST NOT be held while attempting to acquire database connections or + // while executing SQL statements on behalf of the client as it can lead to deadlock. + // + // It is ok to hold the lock while reconfiguring the connection pool or dumping + // statistics because those operations are non-reentrant and do not try to acquire + // connections that might be held by other threads. + // + // Basic rule: grab the lock, access or modify global state, release the lock, then + // do the required SQL work. + private final Object mLock = new Object(); + + // Warns if the database is finalized without being closed properly. + // INVARIANT: Guarded by mLock. + private final CloseGuard mCloseGuardLocked = CloseGuard.get(); + + // The database configuration. + // INVARIANT: Guarded by mLock. + private final SQLiteDatabaseConfiguration mConfigurationLocked; + + // The connection pool for the database, null when closed. + // The pool itself is thread-safe, but the reference to it can only be acquired + // when the lock is held. + // INVARIANT: Guarded by mLock. + private SQLiteConnectionPool mConnectionPoolLocked; + + // True if the database has attached databases. + // INVARIANT: Guarded by mLock. + private boolean mHasAttachedDbsLocked; + + /** + * When a constraint violation occurs, an immediate ROLLBACK occurs, + * thus ending the current transaction, and the command aborts with a + * return code of SQLITE_CONSTRAINT. If no transaction is active + * (other than the implied transaction that is created on every command) + * then this algorithm works the same as ABORT. + */ + public static final int CONFLICT_ROLLBACK = 1; + + /** + * When a constraint violation occurs,no ROLLBACK is executed + * so changes from prior commands within the same transaction + * are preserved. This is the default behavior. + */ + public static final int CONFLICT_ABORT = 2; + + /** + * When a constraint violation occurs, the command aborts with a return + * code SQLITE_CONSTRAINT. But any changes to the database that + * the command made prior to encountering the constraint violation + * are preserved and are not backed out. + */ + public static final int CONFLICT_FAIL = 3; + + /** + * When a constraint violation occurs, the one row that contains + * the constraint violation is not inserted or changed. + * But the command continues executing normally. Other rows before and + * after the row that contained the constraint violation continue to be + * inserted or updated normally. No error is returned. + */ + public static final int CONFLICT_IGNORE = 4; + + /** + * When a UNIQUE constraint violation occurs, the pre-existing rows that + * are causing the constraint violation are removed prior to inserting + * or updating the current row. Thus the insert or update always occurs. + * The command continues executing normally. No error is returned. + * If a NOT NULL constraint violation occurs, the NULL value is replaced + * by the default value for that column. If the column has no default + * value, then the ABORT algorithm is used. If a CHECK constraint + * violation occurs then the IGNORE algorithm is used. When this conflict + * resolution strategy deletes rows in order to satisfy a constraint, + * it does not invoke delete triggers on those rows. + * This behavior might change in a future release. + */ + public static final int CONFLICT_REPLACE = 5; + + /** + * Use the following when no conflict action is specified. + */ + public static final int CONFLICT_NONE = 0; + + private static final String[] CONFLICT_VALUES = new String[] + {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "}; + + /** + * Maximum Length Of A LIKE Or GLOB Pattern + * The pattern matching algorithm used in the default LIKE and GLOB implementation + * of SQLite can exhibit O(N^2) performance (where N is the number of characters in + * the pattern) for certain pathological cases. To avoid denial-of-service attacks + * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes. + * The default value of this limit is 50000. A modern workstation can evaluate + * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly. + * The denial of service problem only comes into play when the pattern length gets + * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns + * are at most a few dozen bytes in length, paranoid application developers may + * want to reduce this parameter to something in the range of a few hundred + * if they know that external users are able to generate arbitrary patterns. + */ + public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000; + + /** + * Open flag: Flag for {@link #openDatabase} to open the database for reading and writing. + * If the disk is full, this may fail even before you actually write anything. + * + * {@more} Note that the value of this flag is 0, so it is the default. + */ + public static final int OPEN_READWRITE = 0x00000000; // update native code if changing + + /** + * Open flag: Flag for {@link #openDatabase} to open the database for reading only. + * This is the only reliable way to open a database if the disk may be full. + */ + public static final int OPEN_READONLY = 0x00000001; // update native code if changing + + private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing + + /** + * Open flag: Flag for {@link #openDatabase} to open the database without support for + * localized collators. + * + * {@more} This causes the collator <code>LOCALIZED</code> not to be created. + * You must be consistent when using this flag to use the setting the database was + * created with. If this is set, {@link #setLocale} will do nothing. + */ + public static final int NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing + + /** + * Open flag: Flag for {@link #openDatabase} to create the database file if it does not + * already exist. + */ + public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing + + /** + * Open flag: Flag for {@link #openDatabase} to open the database file with + * write-ahead logging enabled by default. Using this flag is more efficient + * than calling {@link #enableWriteAheadLogging}. + * + * Write-ahead logging cannot be used with read-only databases so the value of + * this flag is ignored if the database is opened read-only. + * + * @see #enableWriteAheadLogging + */ + public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000; + + /** + * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}. + * + * Each prepared-statement is between 1K - 6K, depending on the complexity of the + * SQL statement & schema. A large SQL cache may use a significant amount of memory. + */ + public static final int MAX_SQL_CACHE_SIZE = 100; + + private SQLiteDatabase(String path, int openFlags, CursorFactory cursorFactory, + DatabaseErrorHandler errorHandler) { + mCursorFactory = cursorFactory; + mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler(); + mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags); + } + + @Override + protected void finalize() throws Throwable { + try { + dispose(true); + } finally { + super.finalize(); + } + } + + @Override + protected void onAllReferencesReleased() { + dispose(false); + } + + private void dispose(boolean finalized) { + final SQLiteConnectionPool pool; + synchronized (mLock) { + if (mCloseGuardLocked != null) { + if (finalized) { + mCloseGuardLocked.warnIfOpen(); + } + mCloseGuardLocked.close(); + } + + pool = mConnectionPoolLocked; + mConnectionPoolLocked = null; + } + + if (!finalized) { + synchronized (sActiveDatabases) { + sActiveDatabases.remove(this); + } + + if (pool != null) { + pool.close(); + } + } + } + + /** + * Attempts to release memory that SQLite holds but does not require to + * operate properly. Typically this memory will come from the page cache. + * + * @return the number of bytes actually released + */ + public static int releaseMemory() { + return SQLiteGlobal.releaseMemory(); + } + + /** + * Control whether or not the SQLiteDatabase is made thread-safe by using locks + * around critical sections. This is pretty expensive, so if you know that your + * DB will only be used by a single thread then you should set this to false. + * The default is true. + * @param lockingEnabled set to true to enable locks, false otherwise + * + * @deprecated This method now does nothing. Do not use. + */ + @Deprecated + public void setLockingEnabled(boolean lockingEnabled) { + } + + /** + * Gets a label to use when describing the database in log messages. + * @return The label. + */ + String getLabel() { + synchronized (mLock) { + return mConfigurationLocked.label; + } + } + + /** + * Sends a corruption message to the database error handler. + */ + void onCorruption() { + EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel()); + mErrorHandler.onCorruption(this); + } + + /** + * Gets the {@link SQLiteSession} that belongs to this thread for this database. + * Once a thread has obtained a session, it will continue to obtain the same + * session even after the database has been closed (although the session will not + * be usable). However, a thread that does not already have a session cannot + * obtain one after the database has been closed. + * + * The idea is that threads that have active connections to the database may still + * have work to complete even after the call to {@link #close}. Active database + * connections are not actually disposed until they are released by the threads + * that own them. + * + * @return The session, never null. + * + * @throws IllegalStateException if the thread does not yet have a session and + * the database is not open. + */ + SQLiteSession getThreadSession() { + return mThreadSession.get(); // initialValue() throws if database closed + } + + SQLiteSession createSession() { + final SQLiteConnectionPool pool; + synchronized (mLock) { + throwIfNotOpenLocked(); + pool = mConnectionPoolLocked; + } + return new SQLiteSession(pool); + } + + /** + * Gets default connection flags that are appropriate for this thread, taking into + * account whether the thread is acting on behalf of the UI. + * + * @param readOnly True if the connection should be read-only. + * @return The connection flags. + */ + int getThreadDefaultConnectionFlags(boolean readOnly) { + int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY : + SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY; + if (isMainThread()) { + flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE; + } + return flags; + } + + private static boolean isMainThread() { + // FIXME: There should be a better way to do this. + // Would also be nice to have something that would work across Binder calls. + Looper looper = Looper.myLooper(); + return looper != null && looper == Looper.getMainLooper(); + } + + /** + * Begins a transaction in EXCLUSIVE mode. + * <p> + * Transactions can be nested. + * When the outer transaction is ended all of + * the work done in that transaction and all of the nested transactions will be committed or + * rolled back. The changes will be rolled back if any transaction is ended without being + * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed. + * </p> + * <p>Here is the standard idiom for transactions: + * + * <pre> + * db.beginTransaction(); + * try { + * ... + * db.setTransactionSuccessful(); + * } finally { + * db.endTransaction(); + * } + * </pre> + */ + public void beginTransaction() { + beginTransaction(null /* transactionStatusCallback */, true); + } + + /** + * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When + * the outer transaction is ended all of the work done in that transaction + * and all of the nested transactions will be committed or rolled back. The + * changes will be rolled back if any transaction is ended without being + * marked as clean (by calling setTransactionSuccessful). Otherwise they + * will be committed. + * <p> + * Here is the standard idiom for transactions: + * + * <pre> + * db.beginTransactionNonExclusive(); + * try { + * ... + * db.setTransactionSuccessful(); + * } finally { + * db.endTransaction(); + * } + * </pre> + */ + public void beginTransactionNonExclusive() { + beginTransaction(null /* transactionStatusCallback */, false); + } + + /** + * Begins a transaction in EXCLUSIVE mode. + * <p> + * Transactions can be nested. + * When the outer transaction is ended all of + * the work done in that transaction and all of the nested transactions will be committed or + * rolled back. The changes will be rolled back if any transaction is ended without being + * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed. + * </p> + * <p>Here is the standard idiom for transactions: + * + * <pre> + * db.beginTransactionWithListener(listener); + * try { + * ... + * db.setTransactionSuccessful(); + * } finally { + * db.endTransaction(); + * } + * </pre> + * + * @param transactionListener listener that should be notified when the transaction begins, + * commits, or is rolled back, either explicitly or by a call to + * {@link #yieldIfContendedSafely}. + */ + public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) { + beginTransaction(transactionListener, true); + } + + /** + * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When + * the outer transaction is ended all of the work done in that transaction + * and all of the nested transactions will be committed or rolled back. The + * changes will be rolled back if any transaction is ended without being + * marked as clean (by calling setTransactionSuccessful). Otherwise they + * will be committed. + * <p> + * Here is the standard idiom for transactions: + * + * <pre> + * db.beginTransactionWithListenerNonExclusive(listener); + * try { + * ... + * db.setTransactionSuccessful(); + * } finally { + * db.endTransaction(); + * } + * </pre> + * + * @param transactionListener listener that should be notified when the + * transaction begins, commits, or is rolled back, either + * explicitly or by a call to {@link #yieldIfContendedSafely}. + */ + public void beginTransactionWithListenerNonExclusive( + SQLiteTransactionListener transactionListener) { + beginTransaction(transactionListener, false); + } + + private void beginTransaction(SQLiteTransactionListener transactionListener, + boolean exclusive) { + acquireReference(); + try { + getThreadSession().beginTransaction( + exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE : + SQLiteSession.TRANSACTION_MODE_IMMEDIATE, + transactionListener, + getThreadDefaultConnectionFlags(false /*readOnly*/), null); + } finally { + releaseReference(); + } + } + + /** + * End a transaction. See beginTransaction for notes about how to use this and when transactions + * are committed and rolled back. + */ + public void endTransaction() { + acquireReference(); + try { + getThreadSession().endTransaction(null); + } finally { + releaseReference(); + } + } + + /** + * Marks the current transaction as successful. Do not do any more database work between + * calling this and calling endTransaction. Do as little non-database work as possible in that + * situation too. If any errors are encountered between this and endTransaction the transaction + * will still be committed. + * + * @throws IllegalStateException if the current thread is not in a transaction or the + * transaction is already marked as successful. + */ + public void setTransactionSuccessful() { + acquireReference(); + try { + getThreadSession().setTransactionSuccessful(); + } finally { + releaseReference(); + } + } + + /** + * Returns true if the current thread has a transaction pending. + * + * @return True if the current thread is in a transaction. + */ + public boolean inTransaction() { + acquireReference(); + try { + return getThreadSession().hasTransaction(); + } finally { + releaseReference(); + } + } + + /** + * Returns true if the current thread is holding an active connection to the database. + * <p> + * The name of this method comes from a time when having an active connection + * to the database meant that the thread was holding an actual lock on the + * database. Nowadays, there is no longer a true "database lock" although threads + * may block if they cannot acquire a database connection to perform a + * particular operation. + * </p> + * + * @return True if the current thread is holding an active connection to the database. + */ + public boolean isDbLockedByCurrentThread() { + acquireReference(); + try { + return getThreadSession().hasConnection(); + } finally { + releaseReference(); + } + } + + /** + * Always returns false. + * <p> + * There is no longer the concept of a database lock, so this method always returns false. + * </p> + * + * @return False. + * @deprecated Always returns false. Do not use this method. + */ + @Deprecated + public boolean isDbLockedByOtherThreads() { + return false; + } + + /** + * Temporarily end the transaction to let other threads run. The transaction is assumed to be + * successful so far. Do not call setTransactionSuccessful before calling this. When this + * returns a new transaction will have been created but not marked as successful. + * @return true if the transaction was yielded + * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock + * will not be yielded. Use yieldIfContendedSafely instead. + */ + @Deprecated + public boolean yieldIfContended() { + return yieldIfContendedHelper(false /* do not check yielding */, + -1 /* sleepAfterYieldDelay */); + } + + /** + * Temporarily end the transaction to let other threads run. The transaction is assumed to be + * successful so far. Do not call setTransactionSuccessful before calling this. When this + * returns a new transaction will have been created but not marked as successful. This assumes + * that there are no nested transactions (beginTransaction has only been called once) and will + * throw an exception if that is not the case. + * @return true if the transaction was yielded + */ + public boolean yieldIfContendedSafely() { + return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/); + } + + /** + * Temporarily end the transaction to let other threads run. The transaction is assumed to be + * successful so far. Do not call setTransactionSuccessful before calling this. When this + * returns a new transaction will have been created but not marked as successful. This assumes + * that there are no nested transactions (beginTransaction has only been called once) and will + * throw an exception if that is not the case. + * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if + * the lock was actually yielded. This will allow other background threads to make some + * more progress than they would if we started the transaction immediately. + * @return true if the transaction was yielded + */ + public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) { + return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay); + } + + private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) { + acquireReference(); + try { + return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null); + } finally { + releaseReference(); + } + } + + /** + * Deprecated. + * @deprecated This method no longer serves any useful purpose and has been deprecated. + */ + @Deprecated + public Map<String, String> getSyncedTables() { + return new HashMap<String, String>(0); + } + + /** + * Open the database according to the flags {@link #OPEN_READWRITE} + * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}. + * + * <p>Sets the locale of the database to the the system's current locale. + * Call {@link #setLocale} if you would like something else.</p> + * + * @param path to database file to open and/or create + * @param factory an optional factory class that is called to instantiate a + * cursor when query is called, or null for default + * @param flags to control database access mode + * @return the newly opened database + * @throws SQLiteException if the database cannot be opened + */ + public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) { + return openDatabase(path, factory, flags, null); + } + + /** + * Open the database according to the flags {@link #OPEN_READWRITE} + * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}. + * + * <p>Sets the locale of the database to the the system's current locale. + * Call {@link #setLocale} if you would like something else.</p> + * + * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be + * used to handle corruption when sqlite reports database corruption.</p> + * + * @param path to database file to open and/or create + * @param factory an optional factory class that is called to instantiate a + * cursor when query is called, or null for default + * @param flags to control database access mode + * @param errorHandler the {@link DatabaseErrorHandler} obj to be used to handle corruption + * when sqlite reports database corruption + * @return the newly opened database + * @throws SQLiteException if the database cannot be opened + */ + public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags, + DatabaseErrorHandler errorHandler) { + SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler); + db.open(); + return db; + } + + /** + * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY). + */ + public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) { + return openOrCreateDatabase(file.getPath(), factory); + } + + /** + * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY). + */ + public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) { + return openDatabase(path, factory, CREATE_IF_NECESSARY, null); + } + + /** + * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler). + */ + public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory, + DatabaseErrorHandler errorHandler) { + return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler); + } + + /** + * Deletes a database including its journal file and other auxiliary files + * that may have been created by the database engine. + * + * @param file The database file path. + * @return True if the database was successfully deleted. + */ + public static boolean deleteDatabase(File file) { + if (file == null) { + throw new IllegalArgumentException("file must not be null"); + } + + boolean deleted = false; + deleted |= file.delete(); + deleted |= new File(file.getPath() + "-journal").delete(); + deleted |= new File(file.getPath() + "-shm").delete(); + deleted |= new File(file.getPath() + "-wal").delete(); + + File dir = file.getParentFile(); + if (dir != null) { + final String prefix = file.getName() + "-mj"; + File[] files = dir.listFiles(new FileFilter() { + @Override + public boolean accept(File candidate) { + return candidate.getName().startsWith(prefix); + } + }); + if (files != null) { + for (File masterJournal : files) { + deleted |= masterJournal.delete(); + } + } + } + return deleted; + } + + /** + * Reopens the database in read-write mode. + * If the database is already read-write, does nothing. + * + * @throws SQLiteException if the database could not be reopened as requested, in which + * case it remains open in read only mode. + * @throws IllegalStateException if the database is not open. + * + * @see #isReadOnly() + * @hide + */ + public void reopenReadWrite() { + synchronized (mLock) { + throwIfNotOpenLocked(); + + if (!isReadOnlyLocked()) { + return; // nothing to do + } + + // Reopen the database in read-write mode. + final int oldOpenFlags = mConfigurationLocked.openFlags; + mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK) + | OPEN_READWRITE; + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.openFlags = oldOpenFlags; + throw ex; + } + } + } + + private void open() { + try { + try { + openInner(); + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + openInner(); + } + } catch (SQLiteException ex) { + Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex); + close(); + throw ex; + } + } + + private void openInner() { + synchronized (mLock) { + assert mConnectionPoolLocked == null; + mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked); + mCloseGuardLocked.open("close"); + } + + synchronized (sActiveDatabases) { + sActiveDatabases.put(this, null); + } + } + + /** + * Create a memory backed SQLite database. Its contents will be destroyed + * when the database is closed. + * + * <p>Sets the locale of the database to the the system's current locale. + * Call {@link #setLocale} if you would like something else.</p> + * + * @param factory an optional factory class that is called to instantiate a + * cursor when query is called + * @return a SQLiteDatabase object, or null if the database can't be created + */ + public static SQLiteDatabase create(CursorFactory factory) { + // This is a magic string with special meaning for SQLite. + return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH, + factory, CREATE_IF_NECESSARY); + } + + /** + * Registers a CustomFunction callback as a function that can be called from + * SQLite database triggers. + * + * @param name the name of the sqlite3 function + * @param numArgs the number of arguments for the function + * @param function callback to call when the function is executed + * @hide + */ + public void addCustomFunction(String name, int numArgs, CustomFunction function) { + // Create wrapper (also validates arguments). + SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function); + + synchronized (mLock) { + throwIfNotOpenLocked(); + + mConfigurationLocked.customFunctions.add(wrapper); + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.customFunctions.remove(wrapper); + throw ex; + } + } + } + + /** + * Gets the database version. + * + * @return the database version + */ + public int getVersion() { + return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue(); + } + + /** + * Sets the database version. + * + * @param version the new database version + */ + public void setVersion(int version) { + execSQL("PRAGMA user_version = " + version); + } + + /** + * Returns the maximum size the database may grow to. + * + * @return the new maximum database size + */ + public long getMaximumSize() { + long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null); + return pageCount * getPageSize(); + } + + /** + * Sets the maximum size the database will grow to. The maximum size cannot + * be set below the current size. + * + * @param numBytes the maximum database size, in bytes + * @return the new maximum database size + */ + public long setMaximumSize(long numBytes) { + long pageSize = getPageSize(); + long numPages = numBytes / pageSize; + // If numBytes isn't a multiple of pageSize, bump up a page + if ((numBytes % pageSize) != 0) { + numPages++; + } + long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages, + null); + return newPageCount * pageSize; + } + + /** + * Returns the current database page size, in bytes. + * + * @return the database page size, in bytes + */ + public long getPageSize() { + return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null); + } + + /** + * Sets the database page size. The page size must be a power of two. This + * method does not work if any data has been written to the database file, + * and must be called right after the database has been created. + * + * @param numBytes the database page size, in bytes + */ + public void setPageSize(long numBytes) { + execSQL("PRAGMA page_size = " + numBytes); + } + + /** + * Mark this table as syncable. When an update occurs in this table the + * _sync_dirty field will be set to ensure proper syncing operation. + * + * @param table the table to mark as syncable + * @param deletedTable The deleted table that corresponds to the + * syncable table + * @deprecated This method no longer serves any useful purpose and has been deprecated. + */ + @Deprecated + public void markTableSyncable(String table, String deletedTable) { + } + + /** + * Mark this table as syncable, with the _sync_dirty residing in another + * table. When an update occurs in this table the _sync_dirty field of the + * row in updateTable with the _id in foreignKey will be set to + * ensure proper syncing operation. + * + * @param table an update on this table will trigger a sync time removal + * @param foreignKey this is the column in table whose value is an _id in + * updateTable + * @param updateTable this is the table that will have its _sync_dirty + * @deprecated This method no longer serves any useful purpose and has been deprecated. + */ + @Deprecated + public void markTableSyncable(String table, String foreignKey, String updateTable) { + } + + /** + * Finds the name of the first table, which is editable. + * + * @param tables a list of tables + * @return the first table listed + */ + public static String findEditTable(String tables) { + if (!TextUtils.isEmpty(tables)) { + // find the first word terminated by either a space or a comma + int spacepos = tables.indexOf(' '); + int commapos = tables.indexOf(','); + + if (spacepos > 0 && (spacepos < commapos || commapos < 0)) { + return tables.substring(0, spacepos); + } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) { + return tables.substring(0, commapos); + } + return tables; + } else { + throw new IllegalStateException("Invalid tables"); + } + } + + /** + * Compiles an SQL statement into a reusable pre-compiled statement object. + * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the + * statement and fill in those values with {@link SQLiteProgram#bindString} + * and {@link SQLiteProgram#bindLong} each time you want to run the + * statement. Statements may not return result sets larger than 1x1. + *<p> + * No two threads should be using the same {@link SQLiteStatement} at the same time. + * + * @param sql The raw SQL statement, may contain ? for unknown values to be + * bound later. + * @return A pre-compiled {@link SQLiteStatement} object. Note that + * {@link SQLiteStatement}s are not synchronized, see the documentation for more details. + */ + public SQLiteStatement compileStatement(String sql) throws SQLException { + acquireReference(); + try { + return new SQLiteStatement(this, sql, null); + } finally { + releaseReference(); + } + } + + /** + * Query the given URL, returning a {@link Cursor} over the result set. + * + * @param distinct true if you want each row to be unique, false otherwise. + * @param table The table name to compile the query against. + * @param columns A list of which columns to return. Passing null will + * return all columns, which is discouraged to prevent reading + * data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, formatted as an + * SQL WHERE clause (excluding the WHERE itself). Passing null + * will return all rows for the given table. + * @param selectionArgs You may include ?s in selection, which will be + * replaced by the values from selectionArgs, in order that they + * appear in the selection. The values will be bound as Strings. + * @param groupBy A filter declaring how to group rows, formatted as an SQL + * GROUP BY clause (excluding the GROUP BY itself). Passing null + * will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in the cursor, + * if row grouping is being used, formatted as an SQL HAVING + * clause (excluding the HAVING itself). Passing null will cause + * all row groups to be included, and is required when row + * grouping is not being used. + * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause + * (excluding the ORDER BY itself). Passing null will use the + * default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + * @see Cursor + */ + public Cursor query(boolean distinct, String table, String[] columns, + String selection, String[] selectionArgs, String groupBy, + String having, String orderBy, String limit) { + return queryWithFactory(null, distinct, table, columns, selection, selectionArgs, + groupBy, having, orderBy, limit, null); + } + + /** + * Query the given URL, returning a {@link Cursor} over the result set. + * + * @param distinct true if you want each row to be unique, false otherwise. + * @param table The table name to compile the query against. + * @param columns A list of which columns to return. Passing null will + * return all columns, which is discouraged to prevent reading + * data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, formatted as an + * SQL WHERE clause (excluding the WHERE itself). Passing null + * will return all rows for the given table. + * @param selectionArgs You may include ?s in selection, which will be + * replaced by the values from selectionArgs, in order that they + * appear in the selection. The values will be bound as Strings. + * @param groupBy A filter declaring how to group rows, formatted as an SQL + * GROUP BY clause (excluding the GROUP BY itself). Passing null + * will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in the cursor, + * if row grouping is being used, formatted as an SQL HAVING + * clause (excluding the HAVING itself). Passing null will cause + * all row groups to be included, and is required when row + * grouping is not being used. + * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause + * (excluding the ORDER BY itself). Passing null will use the + * default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * If the operation is canceled, then {@link OperationCanceledException} will be thrown + * when the query is executed. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + * @see Cursor + */ + public Cursor query(boolean distinct, String table, String[] columns, + String selection, String[] selectionArgs, String groupBy, + String having, String orderBy, String limit, CancellationSignal cancellationSignal) { + return queryWithFactory(null, distinct, table, columns, selection, selectionArgs, + groupBy, having, orderBy, limit, cancellationSignal); + } + + /** + * Query the given URL, returning a {@link Cursor} over the result set. + * + * @param cursorFactory the cursor factory to use, or null for the default factory + * @param distinct true if you want each row to be unique, false otherwise. + * @param table The table name to compile the query against. + * @param columns A list of which columns to return. Passing null will + * return all columns, which is discouraged to prevent reading + * data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, formatted as an + * SQL WHERE clause (excluding the WHERE itself). Passing null + * will return all rows for the given table. + * @param selectionArgs You may include ?s in selection, which will be + * replaced by the values from selectionArgs, in order that they + * appear in the selection. The values will be bound as Strings. + * @param groupBy A filter declaring how to group rows, formatted as an SQL + * GROUP BY clause (excluding the GROUP BY itself). Passing null + * will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in the cursor, + * if row grouping is being used, formatted as an SQL HAVING + * clause (excluding the HAVING itself). Passing null will cause + * all row groups to be included, and is required when row + * grouping is not being used. + * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause + * (excluding the ORDER BY itself). Passing null will use the + * default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + * @see Cursor + */ + public Cursor queryWithFactory(CursorFactory cursorFactory, + boolean distinct, String table, String[] columns, + String selection, String[] selectionArgs, String groupBy, + String having, String orderBy, String limit) { + return queryWithFactory(cursorFactory, distinct, table, columns, selection, + selectionArgs, groupBy, having, orderBy, limit, null); + } + + /** + * Query the given URL, returning a {@link Cursor} over the result set. + * + * @param cursorFactory the cursor factory to use, or null for the default factory + * @param distinct true if you want each row to be unique, false otherwise. + * @param table The table name to compile the query against. + * @param columns A list of which columns to return. Passing null will + * return all columns, which is discouraged to prevent reading + * data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, formatted as an + * SQL WHERE clause (excluding the WHERE itself). Passing null + * will return all rows for the given table. + * @param selectionArgs You may include ?s in selection, which will be + * replaced by the values from selectionArgs, in order that they + * appear in the selection. The values will be bound as Strings. + * @param groupBy A filter declaring how to group rows, formatted as an SQL + * GROUP BY clause (excluding the GROUP BY itself). Passing null + * will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in the cursor, + * if row grouping is being used, formatted as an SQL HAVING + * clause (excluding the HAVING itself). Passing null will cause + * all row groups to be included, and is required when row + * grouping is not being used. + * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause + * (excluding the ORDER BY itself). Passing null will use the + * default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * If the operation is canceled, then {@link OperationCanceledException} will be thrown + * when the query is executed. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + * @see Cursor + */ + public Cursor queryWithFactory(CursorFactory cursorFactory, + boolean distinct, String table, String[] columns, + String selection, String[] selectionArgs, String groupBy, + String having, String orderBy, String limit, CancellationSignal cancellationSignal) { + acquireReference(); + try { + String sql = SQLiteQueryBuilder.buildQueryString( + distinct, table, columns, selection, groupBy, having, orderBy, limit); + + return rawQueryWithFactory(cursorFactory, sql, selectionArgs, + findEditTable(table), cancellationSignal); + } finally { + releaseReference(); + } + } + + /** + * Query the given table, returning a {@link Cursor} over the result set. + * + * @param table The table name to compile the query against. + * @param columns A list of which columns to return. Passing null will + * return all columns, which is discouraged to prevent reading + * data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, formatted as an + * SQL WHERE clause (excluding the WHERE itself). Passing null + * will return all rows for the given table. + * @param selectionArgs You may include ?s in selection, which will be + * replaced by the values from selectionArgs, in order that they + * appear in the selection. The values will be bound as Strings. + * @param groupBy A filter declaring how to group rows, formatted as an SQL + * GROUP BY clause (excluding the GROUP BY itself). Passing null + * will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in the cursor, + * if row grouping is being used, formatted as an SQL HAVING + * clause (excluding the HAVING itself). Passing null will cause + * all row groups to be included, and is required when row + * grouping is not being used. + * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause + * (excluding the ORDER BY itself). Passing null will use the + * default sort order, which may be unordered. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + * @see Cursor + */ + public Cursor query(String table, String[] columns, String selection, + String[] selectionArgs, String groupBy, String having, + String orderBy) { + + return query(false, table, columns, selection, selectionArgs, groupBy, + having, orderBy, null /* limit */); + } + + /** + * Query the given table, returning a {@link Cursor} over the result set. + * + * @param table The table name to compile the query against. + * @param columns A list of which columns to return. Passing null will + * return all columns, which is discouraged to prevent reading + * data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, formatted as an + * SQL WHERE clause (excluding the WHERE itself). Passing null + * will return all rows for the given table. + * @param selectionArgs You may include ?s in selection, which will be + * replaced by the values from selectionArgs, in order that they + * appear in the selection. The values will be bound as Strings. + * @param groupBy A filter declaring how to group rows, formatted as an SQL + * GROUP BY clause (excluding the GROUP BY itself). Passing null + * will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in the cursor, + * if row grouping is being used, formatted as an SQL HAVING + * clause (excluding the HAVING itself). Passing null will cause + * all row groups to be included, and is required when row + * grouping is not being used. + * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause + * (excluding the ORDER BY itself). Passing null will use the + * default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + * @see Cursor + */ + public Cursor query(String table, String[] columns, String selection, + String[] selectionArgs, String groupBy, String having, + String orderBy, String limit) { + + return query(false, table, columns, selection, selectionArgs, groupBy, + having, orderBy, limit); + } + + /** + * Runs the provided SQL and returns a {@link Cursor} over the result set. + * + * @param sql the SQL query. The SQL string must not be ; terminated + * @param selectionArgs You may include ?s in where clause in the query, + * which will be replaced by the values from selectionArgs. The + * values will be bound as Strings. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + */ + public Cursor rawQuery(String sql, String[] selectionArgs) { + return rawQueryWithFactory(null, sql, selectionArgs, null, null); + } + + /** + * Runs the provided SQL and returns a {@link Cursor} over the result set. + * + * @param sql the SQL query. The SQL string must not be ; terminated + * @param selectionArgs You may include ?s in where clause in the query, + * which will be replaced by the values from selectionArgs. The + * values will be bound as Strings. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * If the operation is canceled, then {@link OperationCanceledException} will be thrown + * when the query is executed. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + */ + public Cursor rawQuery(String sql, String[] selectionArgs, + CancellationSignal cancellationSignal) { + return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal); + } + + /** + * Runs the provided SQL and returns a cursor over the result set. + * + * @param cursorFactory the cursor factory to use, or null for the default factory + * @param sql the SQL query. The SQL string must not be ; terminated + * @param selectionArgs You may include ?s in where clause in the query, + * which will be replaced by the values from selectionArgs. The + * values will be bound as Strings. + * @param editTable the name of the first table, which is editable + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + */ + public Cursor rawQueryWithFactory( + CursorFactory cursorFactory, String sql, String[] selectionArgs, + String editTable) { + return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null); + } + + /** + * Runs the provided SQL and returns a cursor over the result set. + * + * @param cursorFactory the cursor factory to use, or null for the default factory + * @param sql the SQL query. The SQL string must not be ; terminated + * @param selectionArgs You may include ?s in where clause in the query, + * which will be replaced by the values from selectionArgs. The + * values will be bound as Strings. + * @param editTable the name of the first table, which is editable + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * If the operation is canceled, then {@link OperationCanceledException} will be thrown + * when the query is executed. + * @return A {@link Cursor} object, which is positioned before the first entry. Note that + * {@link Cursor}s are not synchronized, see the documentation for more details. + */ + public Cursor rawQueryWithFactory( + CursorFactory cursorFactory, String sql, String[] selectionArgs, + String editTable, CancellationSignal cancellationSignal) { + acquireReference(); + try { + SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable, + cancellationSignal); + return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory, + selectionArgs); + } finally { + releaseReference(); + } + } + + /** + * Convenience method for inserting a row into the database. + * + * @param table the table to insert the row into + * @param nullColumnHack optional; may be <code>null</code>. + * SQL doesn't allow inserting a completely empty row without + * naming at least one column name. If your provided <code>values</code> is + * empty, no column names are known and an empty row can't be inserted. + * If not set to null, the <code>nullColumnHack</code> parameter + * provides the name of nullable column name to explicitly insert a NULL into + * in the case where your <code>values</code> is empty. + * @param values this map contains the initial column values for the + * row. The keys should be the column names and the values the + * column values + * @return the row ID of the newly inserted row, or -1 if an error occurred + */ + public long insert(String table, String nullColumnHack, ContentValues values) { + try { + return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); + } catch (SQLException e) { + Log.e(TAG, "Error inserting " + values, e); + return -1; + } + } + + /** + * Convenience method for inserting a row into the database. + * + * @param table the table to insert the row into + * @param nullColumnHack optional; may be <code>null</code>. + * SQL doesn't allow inserting a completely empty row without + * naming at least one column name. If your provided <code>values</code> is + * empty, no column names are known and an empty row can't be inserted. + * If not set to null, the <code>nullColumnHack</code> parameter + * provides the name of nullable column name to explicitly insert a NULL into + * in the case where your <code>values</code> is empty. + * @param values this map contains the initial column values for the + * row. The keys should be the column names and the values the + * column values + * @throws SQLException + * @return the row ID of the newly inserted row, or -1 if an error occurred + */ + public long insertOrThrow(String table, String nullColumnHack, ContentValues values) + throws SQLException { + return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); + } + + /** + * Convenience method for replacing a row in the database. + * Inserts a new row if a row does not already exist. + * + * @param table the table in which to replace the row + * @param nullColumnHack optional; may be <code>null</code>. + * SQL doesn't allow inserting a completely empty row without + * naming at least one column name. If your provided <code>initialValues</code> is + * empty, no column names are known and an empty row can't be inserted. + * If not set to null, the <code>nullColumnHack</code> parameter + * provides the name of nullable column name to explicitly insert a NULL into + * in the case where your <code>initialValues</code> is empty. + * @param initialValues this map contains the initial column values for + * the row. The keys should be the column names and the values the column values. + * @return the row ID of the newly inserted row, or -1 if an error occurred + */ + public long replace(String table, String nullColumnHack, ContentValues initialValues) { + try { + return insertWithOnConflict(table, nullColumnHack, initialValues, + CONFLICT_REPLACE); + } catch (SQLException e) { + Log.e(TAG, "Error inserting " + initialValues, e); + return -1; + } + } + + /** + * Convenience method for replacing a row in the database. + * Inserts a new row if a row does not already exist. + * + * @param table the table in which to replace the row + * @param nullColumnHack optional; may be <code>null</code>. + * SQL doesn't allow inserting a completely empty row without + * naming at least one column name. If your provided <code>initialValues</code> is + * empty, no column names are known and an empty row can't be inserted. + * If not set to null, the <code>nullColumnHack</code> parameter + * provides the name of nullable column name to explicitly insert a NULL into + * in the case where your <code>initialValues</code> is empty. + * @param initialValues this map contains the initial column values for + * the row. The keys should be the column names and the values the column values. + * @throws SQLException + * @return the row ID of the newly inserted row, or -1 if an error occurred + */ + public long replaceOrThrow(String table, String nullColumnHack, + ContentValues initialValues) throws SQLException { + return insertWithOnConflict(table, nullColumnHack, initialValues, + CONFLICT_REPLACE); + } + + /** + * General method for inserting a row into the database. + * + * @param table the table to insert the row into + * @param nullColumnHack optional; may be <code>null</code>. + * SQL doesn't allow inserting a completely empty row without + * naming at least one column name. If your provided <code>initialValues</code> is + * empty, no column names are known and an empty row can't be inserted. + * If not set to null, the <code>nullColumnHack</code> parameter + * provides the name of nullable column name to explicitly insert a NULL into + * in the case where your <code>initialValues</code> is empty. + * @param initialValues this map contains the initial column values for the + * row. The keys should be the column names and the values the + * column values + * @param conflictAlgorithm for insert conflict resolver + * @return the row ID of the newly inserted row OR <code>-1</code> if either the + * input parameter <code>conflictAlgorithm</code> = {@link #CONFLICT_IGNORE} + * or an error occurred. + */ + public long insertWithOnConflict(String table, String nullColumnHack, + ContentValues initialValues, int conflictAlgorithm) { + acquireReference(); + try { + StringBuilder sql = new StringBuilder(); + sql.append("INSERT"); + sql.append(CONFLICT_VALUES[conflictAlgorithm]); + sql.append(" INTO "); + sql.append(table); + sql.append('('); + + Object[] bindArgs = null; + int size = (initialValues != null && initialValues.size() > 0) + ? initialValues.size() : 0; + if (size > 0) { + bindArgs = new Object[size]; + int i = 0; + for (String colName : initialValues.keySet()) { + sql.append((i > 0) ? "," : ""); + sql.append(colName); + bindArgs[i++] = initialValues.get(colName); + } + sql.append(')'); + sql.append(" VALUES ("); + for (i = 0; i < size; i++) { + sql.append((i > 0) ? ",?" : "?"); + } + } else { + sql.append(nullColumnHack + ") VALUES (NULL"); + } + sql.append(')'); + + SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); + try { + return statement.executeInsert(); + } finally { + statement.close(); + } + } finally { + releaseReference(); + } + } + + /** + * Convenience method for deleting rows in the database. + * + * @param table the table to delete from + * @param whereClause the optional WHERE clause to apply when deleting. + * Passing null will delete all rows. + * @param whereArgs You may include ?s in the where clause, which + * will be replaced by the values from whereArgs. The values + * will be bound as Strings. + * @return the number of rows affected if a whereClause is passed in, 0 + * otherwise. To remove all rows and get a count pass "1" as the + * whereClause. + */ + public int delete(String table, String whereClause, String[] whereArgs) { + acquireReference(); + try { + SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table + + (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs); + try { + return statement.executeUpdateDelete(); + } finally { + statement.close(); + } + } finally { + releaseReference(); + } + } + + /** + * Convenience method for updating rows in the database. + * + * @param table the table to update in + * @param values a map from column names to new column values. null is a + * valid value that will be translated to NULL. + * @param whereClause the optional WHERE clause to apply when updating. + * Passing null will update all rows. + * @param whereArgs You may include ?s in the where clause, which + * will be replaced by the values from whereArgs. The values + * will be bound as Strings. + * @return the number of rows affected + */ + public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { + return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE); + } + + /** + * Convenience method for updating rows in the database. + * + * @param table the table to update in + * @param values a map from column names to new column values. null is a + * valid value that will be translated to NULL. + * @param whereClause the optional WHERE clause to apply when updating. + * Passing null will update all rows. + * @param whereArgs You may include ?s in the where clause, which + * will be replaced by the values from whereArgs. The values + * will be bound as Strings. + * @param conflictAlgorithm for update conflict resolver + * @return the number of rows affected + */ + public int updateWithOnConflict(String table, ContentValues values, + String whereClause, String[] whereArgs, int conflictAlgorithm) { + if (values == null || values.size() == 0) { + throw new IllegalArgumentException("Empty values"); + } + + acquireReference(); + try { + StringBuilder sql = new StringBuilder(120); + sql.append("UPDATE "); + sql.append(CONFLICT_VALUES[conflictAlgorithm]); + sql.append(table); + sql.append(" SET "); + + // move all bind args to one array + int setValuesSize = values.size(); + int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length); + Object[] bindArgs = new Object[bindArgsSize]; + int i = 0; + for (String colName : values.keySet()) { + sql.append((i > 0) ? "," : ""); + sql.append(colName); + bindArgs[i++] = values.get(colName); + sql.append("=?"); + } + if (whereArgs != null) { + for (i = setValuesSize; i < bindArgsSize; i++) { + bindArgs[i] = whereArgs[i - setValuesSize]; + } + } + if (!TextUtils.isEmpty(whereClause)) { + sql.append(" WHERE "); + sql.append(whereClause); + } + + SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); + try { + return statement.executeUpdateDelete(); + } finally { + statement.close(); + } + } finally { + releaseReference(); + } + } + + /** + * Execute a single SQL statement that is NOT a SELECT + * or any other SQL statement that returns data. + * <p> + * It has no means to return any data (such as the number of affected rows). + * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)}, + * {@link #update(String, ContentValues, String, String[])}, et al, when possible. + * </p> + * <p> + * When using {@link #enableWriteAheadLogging()}, journal_mode is + * automatically managed by this class. So, do not set journal_mode + * using "PRAGMA journal_mode'<value>" statement if your app is using + * {@link #enableWriteAheadLogging()} + * </p> + * + * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are + * not supported. + * @throws SQLException if the SQL string is invalid + */ + public void execSQL(String sql) throws SQLException { + executeSql(sql, null); + } + + /** + * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE. + * <p> + * For INSERT statements, use any of the following instead. + * <ul> + * <li>{@link #insert(String, String, ContentValues)}</li> + * <li>{@link #insertOrThrow(String, String, ContentValues)}</li> + * <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li> + * </ul> + * <p> + * For UPDATE statements, use any of the following instead. + * <ul> + * <li>{@link #update(String, ContentValues, String, String[])}</li> + * <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li> + * </ul> + * <p> + * For DELETE statements, use any of the following instead. + * <ul> + * <li>{@link #delete(String, String, String[])}</li> + * </ul> + * <p> + * For example, the following are good candidates for using this method: + * <ul> + * <li>ALTER TABLE</li> + * <li>CREATE or DROP table / trigger / view / index / virtual table</li> + * <li>REINDEX</li> + * <li>RELEASE</li> + * <li>SAVEPOINT</li> + * <li>PRAGMA that returns no data</li> + * </ul> + * </p> + * <p> + * When using {@link #enableWriteAheadLogging()}, journal_mode is + * automatically managed by this class. So, do not set journal_mode + * using "PRAGMA journal_mode'<value>" statement if your app is using + * {@link #enableWriteAheadLogging()} + * </p> + * + * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are + * not supported. + * @param bindArgs only byte[], String, Long and Double are supported in bindArgs. + * @throws SQLException if the SQL string is invalid + */ + public void execSQL(String sql, Object[] bindArgs) throws SQLException { + if (bindArgs == null) { + throw new IllegalArgumentException("Empty bindArgs"); + } + executeSql(sql, bindArgs); + } + + private int executeSql(String sql, Object[] bindArgs) throws SQLException { + acquireReference(); + try { + if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) { + boolean disableWal = false; + synchronized (mLock) { + if (!mHasAttachedDbsLocked) { + mHasAttachedDbsLocked = true; + disableWal = true; + } + } + if (disableWal) { + disableWriteAheadLogging(); + } + } + + SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs); + try { + return statement.executeUpdateDelete(); + } finally { + statement.close(); + } + } finally { + releaseReference(); + } + } + + /** + * Verifies that a SQL SELECT statement is valid by compiling it. + * If the SQL statement is not valid, this method will throw a {@link SQLiteException}. + * + * @param sql SQL to be validated + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * If the operation is canceled, then {@link OperationCanceledException} will be thrown + * when the query is executed. + * @throws SQLiteException if {@code sql} is invalid + */ + public void validateSql(String sql, CancellationSignal cancellationSignal) { + getThreadSession().prepare(sql, + getThreadDefaultConnectionFlags(/* readOnly =*/ true), cancellationSignal, null); + } + + /** + * Returns true if the database is opened as read only. + * + * @return True if database is opened as read only. + */ + public boolean isReadOnly() { + synchronized (mLock) { + return isReadOnlyLocked(); + } + } + + private boolean isReadOnlyLocked() { + return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY; + } + + /** + * Returns true if the database is in-memory db. + * + * @return True if the database is in-memory. + * @hide + */ + public boolean isInMemoryDatabase() { + synchronized (mLock) { + return mConfigurationLocked.isInMemoryDb(); + } + } + + /** + * Returns true if the database is currently open. + * + * @return True if the database is currently open (has not been closed). + */ + public boolean isOpen() { + synchronized (mLock) { + return mConnectionPoolLocked != null; + } + } + + /** + * Returns true if the new version code is greater than the current database version. + * + * @param newVersion The new version code. + * @return True if the new version code is greater than the current database version. + */ + public boolean needUpgrade(int newVersion) { + return newVersion > getVersion(); + } + + /** + * Gets the path to the database file. + * + * @return The path to the database file. + */ + public final String getPath() { + synchronized (mLock) { + return mConfigurationLocked.path; + } + } + + /** + * Sets the locale for this database. Does nothing if this database has + * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only. + * + * @param locale The new locale. + * + * @throws SQLException if the locale could not be set. The most common reason + * for this is that there is no collator available for the locale you requested. + * In this case the database remains unchanged. + */ + public void setLocale(Locale locale) { + if (locale == null) { + throw new IllegalArgumentException("locale must not be null."); + } + + synchronized (mLock) { + throwIfNotOpenLocked(); + + final Locale oldLocale = mConfigurationLocked.locale; + mConfigurationLocked.locale = locale; + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.locale = oldLocale; + throw ex; + } + } + } + + /** + * Sets the maximum size of the prepared-statement cache for this database. + * (size of the cache = number of compiled-sql-statements stored in the cache). + *<p> + * Maximum cache size can ONLY be increased from its current size (default = 10). + * If this method is called with smaller size than the current maximum value, + * then IllegalStateException is thrown. + *<p> + * This method is thread-safe. + * + * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE}) + * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}. + */ + public void setMaxSqlCacheSize(int cacheSize) { + if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) { + throw new IllegalStateException( + "expected value between 0 and " + MAX_SQL_CACHE_SIZE); + } + + synchronized (mLock) { + throwIfNotOpenLocked(); + + final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize; + mConfigurationLocked.maxSqlCacheSize = cacheSize; + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize; + throw ex; + } + } + } + + /** + * Sets whether foreign key constraints are enabled for the database. + * <p> + * By default, foreign key constraints are not enforced by the database. + * This method allows an application to enable foreign key constraints. + * It must be called each time the database is opened to ensure that foreign + * key constraints are enabled for the session. + * </p><p> + * A good time to call this method is right after calling {@link #openOrCreateDatabase} + * or in the {@link SQLiteOpenHelper#onConfigure} callback. + * </p><p> + * When foreign key constraints are disabled, the database does not check whether + * changes to the database will violate foreign key constraints. Likewise, when + * foreign key constraints are disabled, the database will not execute cascade + * delete or update triggers. As a result, it is possible for the database + * state to become inconsistent. To perform a database integrity check, + * call {@link #isDatabaseIntegrityOk}. + * </p><p> + * This method must not be called while a transaction is in progress. + * </p><p> + * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a> + * for more details about foreign key constraint support. + * </p> + * + * @param enable True to enable foreign key constraints, false to disable them. + * + * @throws IllegalStateException if the are transactions is in progress + * when this method is called. + */ + public void setForeignKeyConstraintsEnabled(boolean enable) { + synchronized (mLock) { + throwIfNotOpenLocked(); + + if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) { + return; + } + + mConfigurationLocked.foreignKeyConstraintsEnabled = enable; + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.foreignKeyConstraintsEnabled = !enable; + throw ex; + } + } + } + + /** + * This method enables parallel execution of queries from multiple threads on the + * same database. It does this by opening multiple connections to the database + * and using a different database connection for each query. The database + * journal mode is also changed to enable writes to proceed concurrently with reads. + * <p> + * When write-ahead logging is not enabled (the default), it is not possible for + * reads and writes to occur on the database at the same time. Before modifying the + * database, the writer implicitly acquires an exclusive lock on the database which + * prevents readers from accessing the database until the write is completed. + * </p><p> + * In contrast, when write-ahead logging is enabled (by calling this method), write + * operations occur in a separate log file which allows reads to proceed concurrently. + * While a write is in progress, readers on other threads will perceive the state + * of the database as it was before the write began. When the write completes, readers + * on other threads will then perceive the new state of the database. + * </p><p> + * It is a good idea to enable write-ahead logging whenever a database will be + * concurrently accessed and modified by multiple threads at the same time. + * However, write-ahead logging uses significantly more memory than ordinary + * journaling because there are multiple connections to the same database. + * So if a database will only be used by a single thread, or if optimizing + * concurrency is not very important, then write-ahead logging should be disabled. + * </p><p> + * After calling this method, execution of queries in parallel is enabled as long as + * the database remains open. To disable execution of queries in parallel, either + * call {@link #disableWriteAheadLogging} or close the database and reopen it. + * </p><p> + * The maximum number of connections used to execute queries in parallel is + * dependent upon the device memory and possibly other properties. + * </p><p> + * If a query is part of a transaction, then it is executed on the same database handle the + * transaction was begun. + * </p><p> + * Writers should use {@link #beginTransactionNonExclusive()} or + * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)} + * to start a transaction. Non-exclusive mode allows database file to be in readable + * by other threads executing queries. + * </p><p> + * If the database has any attached databases, then execution of queries in parallel is NOT + * possible. Likewise, write-ahead logging is not supported for read-only databases + * or memory databases. In such cases, {@link #enableWriteAheadLogging} returns false. + * </p><p> + * The best way to enable write-ahead logging is to pass the + * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}. This is + * more efficient than calling {@link #enableWriteAheadLogging}. + * <code><pre> + * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory, + * SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING, + * myDatabaseErrorHandler); + * db.enableWriteAheadLogging(); + * </pre></code> + * </p><p> + * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging} + * after opening the database. + * <code><pre> + * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory, + * SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler); + * db.enableWriteAheadLogging(); + * </pre></code> + * </p><p> + * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for + * more details about how write-ahead logging works. + * </p> + * + * @return True if write-ahead logging is enabled. + * + * @throws IllegalStateException if there are transactions in progress at the + * time this method is called. WAL mode can only be changed when there are no + * transactions in progress. + * + * @see #ENABLE_WRITE_AHEAD_LOGGING + * @see #disableWriteAheadLogging + */ + public boolean enableWriteAheadLogging() { + synchronized (mLock) { + throwIfNotOpenLocked(); + + if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) { + return true; + } + + if (isReadOnlyLocked()) { + // WAL doesn't make sense for readonly-databases. + // TODO: True, but connection pooling does still make sense... + return false; + } + + if (mConfigurationLocked.isInMemoryDb()) { + Log.i(TAG, "can't enable WAL for memory databases."); + return false; + } + + // make sure this database has NO attached databases because sqlite's write-ahead-logging + // doesn't work for databases with attached databases + if (mHasAttachedDbsLocked) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "this database: " + mConfigurationLocked.label + + " has attached databases. can't enable WAL."); + } + return false; + } + + mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING; + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING; + throw ex; + } + } + return true; + } + + /** + * This method disables the features enabled by {@link #enableWriteAheadLogging()}. + * + * @throws IllegalStateException if there are transactions in progress at the + * time this method is called. WAL mode can only be changed when there are no + * transactions in progress. + * + * @see #enableWriteAheadLogging + */ + public void disableWriteAheadLogging() { + synchronized (mLock) { + throwIfNotOpenLocked(); + + if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) { + return; + } + + mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING; + try { + mConnectionPoolLocked.reconfigure(mConfigurationLocked); + } catch (RuntimeException ex) { + mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING; + throw ex; + } + } + } + + /** + * Returns true if write-ahead logging has been enabled for this database. + * + * @return True if write-ahead logging has been enabled for this database. + * + * @see #enableWriteAheadLogging + * @see #ENABLE_WRITE_AHEAD_LOGGING + */ + public boolean isWriteAheadLoggingEnabled() { + synchronized (mLock) { + throwIfNotOpenLocked(); + + return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0; + } + } + + /** + * Collect statistics about all open databases in the current process. + * Used by bug report. + */ + static ArrayList<DbStats> getDbStats() { + ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>(); + for (SQLiteDatabase db : getActiveDatabases()) { + db.collectDbStats(dbStatsList); + } + return dbStatsList; + } + + private void collectDbStats(ArrayList<DbStats> dbStatsList) { + synchronized (mLock) { + if (mConnectionPoolLocked != null) { + mConnectionPoolLocked.collectDbStats(dbStatsList); + } + } + } + + private static ArrayList<SQLiteDatabase> getActiveDatabases() { + ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>(); + synchronized (sActiveDatabases) { + databases.addAll(sActiveDatabases.keySet()); + } + return databases; + } + + /** + * Dump detailed information about all open databases in the current process. + * Used by bug report. + */ + static void dumpAll(Printer printer, boolean verbose) { + for (SQLiteDatabase db : getActiveDatabases()) { + db.dump(printer, verbose); + } + } + + private void dump(Printer printer, boolean verbose) { + synchronized (mLock) { + if (mConnectionPoolLocked != null) { + printer.println(""); + mConnectionPoolLocked.dump(printer, verbose); + } + } + } + + /** + * Returns list of full pathnames of all attached databases including the main database + * by executing 'pragma database_list' on the database. + * + * @return ArrayList of pairs of (database name, database file path) or null if the database + * is not open. + */ + public List<Pair<String, String>> getAttachedDbs() { + ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>(); + synchronized (mLock) { + if (mConnectionPoolLocked == null) { + return null; // not open + } + + if (!mHasAttachedDbsLocked) { + // No attached databases. + // There is a small window where attached databases exist but this flag is not + // set yet. This can occur when this thread is in a race condition with another + // thread that is executing the SQL statement: "attach database <blah> as <foo>" + // If this thread is NOT ok with such a race condition (and thus possibly not + // receivethe entire list of attached databases), then the caller should ensure + // that no thread is executing any SQL statements while a thread is calling this + // method. Typically, this method is called when 'adb bugreport' is done or the + // caller wants to collect stats on the database and all its attached databases. + attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path)); + return attachedDbs; + } + + acquireReference(); + } + + try { + // has attached databases. query sqlite to get the list of attached databases. + Cursor c = null; + try { + c = rawQuery("pragma database_list;", null); + while (c.moveToNext()) { + // sqlite returns a row for each database in the returned list of databases. + // in each row, + // 1st column is the database name such as main, or the database + // name specified on the "ATTACH" command + // 2nd column is the database file path. + attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2))); + } + } finally { + if (c != null) { + c.close(); + } + } + return attachedDbs; + } finally { + releaseReference(); + } + } + + /** + * Runs 'pragma integrity_check' on the given database (and all the attached databases) + * and returns true if the given database (and all its attached databases) pass integrity_check, + * false otherwise. + *<p> + * If the result is false, then this method logs the errors reported by the integrity_check + * command execution. + *<p> + * Note that 'pragma integrity_check' on a database can take a long time. + * + * @return true if the given database (and all its attached databases) pass integrity_check, + * false otherwise. + */ + public boolean isDatabaseIntegrityOk() { + acquireReference(); + try { + List<Pair<String, String>> attachedDbs = null; + try { + attachedDbs = getAttachedDbs(); + if (attachedDbs == null) { + throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " + + "be retrieved. probably because the database is closed"); + } + } catch (SQLiteException e) { + // can't get attachedDb list. do integrity check on the main database + attachedDbs = new ArrayList<Pair<String, String>>(); + attachedDbs.add(new Pair<String, String>("main", getPath())); + } + + for (int i = 0; i < attachedDbs.size(); i++) { + Pair<String, String> p = attachedDbs.get(i); + SQLiteStatement prog = null; + try { + prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);"); + String rslt = prog.simpleQueryForString(); + if (!rslt.equalsIgnoreCase("ok")) { + // integrity_checker failed on main or attached databases + Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt); + return false; + } + } finally { + if (prog != null) prog.close(); + } + } + } finally { + releaseReference(); + } + return true; + } + + @Override + public String toString() { + return "SQLiteDatabase: " + getPath(); + } + + private void throwIfNotOpenLocked() { + if (mConnectionPoolLocked == null) { + throw new IllegalStateException("The database '" + mConfigurationLocked.label + + "' is not open."); + } + } + + /** + * Used to allow returning sub-classes of {@link Cursor} when calling query. + */ + public interface CursorFactory { + /** + * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}. + */ + public Cursor newCursor(SQLiteDatabase db, + SQLiteCursorDriver masterQuery, String editTable, + SQLiteQuery query); + } + + /** + * A callback interface for a custom sqlite3 function. + * This can be used to create a function that can be called from + * sqlite3 database triggers. + * @hide + */ + public interface CustomFunction { + public void callback(String[] args); + } + + public static boolean hasCodec() { + return SQLiteConnection.hasCodec(); + } + + public void enableLocalizedCollators() { + mConnectionPoolLocked.enableLocalizedCollators(); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabaseConfiguration.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabaseConfiguration.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import java.util.ArrayList; +import java.util.Locale; +import java.util.regex.Pattern; + +/** + * Describes how to configure a database. + * <p> + * The purpose of this object is to keep track of all of the little + * configuration settings that are applied to a database after it + * is opened so that they can be applied to all connections in the + * connection pool uniformly. + * </p><p> + * Each connection maintains its own copy of this object so it can + * keep track of which settings have already been applied. + * </p> + * + * @hide + */ +public final class SQLiteDatabaseConfiguration { + // The pattern we use to strip email addresses from database paths + // when constructing a label to use in log messages. + private static final Pattern EMAIL_IN_DB_PATTERN = + Pattern.compile("[\\w\\.\\-]+@[\\w\\.\\-]+"); + + /** + * Special path used by in-memory databases. + */ + public static final String MEMORY_DB_PATH = ":memory:"; + + /** + * The database path. + */ + public final String path; + + /** + * The label to use to describe the database when it appears in logs. + * This is derived from the path but is stripped to remove PII. + */ + public final String label; + + /** + * The flags used to open the database. + */ + public int openFlags; + + /** + * The maximum size of the prepared statement cache for each database connection. + * Must be non-negative. + * + * Default is 25. + */ + public int maxSqlCacheSize; + + /** + * The database locale. + * + * Default is the value returned by {@link Locale#getDefault()}. + */ + public Locale locale; + + /** + * True if foreign key constraints are enabled. + * + * Default is false. + */ + public boolean foreignKeyConstraintsEnabled; + + /** + * The custom functions to register. + */ + public final ArrayList<SQLiteCustomFunction> customFunctions = + new ArrayList<SQLiteCustomFunction>(); + + /** + * Creates a database configuration with the required parameters for opening a + * database and default values for all other parameters. + * + * @param path The database path. + * @param openFlags Open flags for the database, such as {@link SQLiteDatabase#OPEN_READWRITE}. + */ + public SQLiteDatabaseConfiguration(String path, int openFlags) { + if (path == null) { + throw new IllegalArgumentException("path must not be null."); + } + + this.path = path; + label = stripPathForLogs(path); + this.openFlags = openFlags; + + // Set default values for optional parameters. + maxSqlCacheSize = 25; + locale = Locale.getDefault(); + } + + /** + * Creates a database configuration as a copy of another configuration. + * + * @param other The other configuration. + */ + public SQLiteDatabaseConfiguration(SQLiteDatabaseConfiguration other) { + if (other == null) { + throw new IllegalArgumentException("other must not be null."); + } + + this.path = other.path; + this.label = other.label; + updateParametersFrom(other); + } + + /** + * Updates the non-immutable parameters of this configuration object + * from the other configuration object. + * + * @param other The object from which to copy the parameters. + */ + public void updateParametersFrom(SQLiteDatabaseConfiguration other) { + if (other == null) { + throw new IllegalArgumentException("other must not be null."); + } + if (!path.equals(other.path)) { + throw new IllegalArgumentException("other configuration must refer to " + + "the same database."); + } + + openFlags = other.openFlags; + maxSqlCacheSize = other.maxSqlCacheSize; + locale = other.locale; + foreignKeyConstraintsEnabled = other.foreignKeyConstraintsEnabled; + customFunctions.clear(); + customFunctions.addAll(other.customFunctions); + } + + /** + * Returns true if the database is in-memory. + * @return True if the database is in-memory. + */ + public boolean isInMemoryDb() { + return path.equalsIgnoreCase(MEMORY_DB_PATH); + } + + private static String stripPathForLogs(String path) { + /* Strip off all URI parameters. This is in case a SEE database is + * opened with the password specified as a URI parameter. We do not + * want the password to appear in any log files. */ + int iIdx = path.indexOf('?'); + if( iIdx>=0 ){ + path = (String) path.subSequence(0, iIdx); + } + + if (path.indexOf('@') == -1) { + return path; + } + return EMAIL_IN_DB_PATTERN.matcher(path).replaceAll("XX@YY"); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabaseCorruptException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabaseCorruptException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * An exception that indicates that the SQLite database file is corrupt. + */ +public class SQLiteDatabaseCorruptException extends SQLiteException { + public SQLiteDatabaseCorruptException() {} + + public SQLiteDatabaseCorruptException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabaseLockedException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatabaseLockedException.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * Thrown if the database engine was unable to acquire the + * database locks it needs to do its job. If the statement is a [COMMIT] + * or occurs outside of an explicit transaction, then you can retry the + * statement. If the statement is not a [COMMIT] and occurs within a + * explicit transaction then you should rollback the transaction before + * continuing. + */ +public class SQLiteDatabaseLockedException extends SQLiteException { + public SQLiteDatabaseLockedException() {} + + public SQLiteDatabaseLockedException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatatypeMismatchException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDatatypeMismatchException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +public class SQLiteDatatypeMismatchException extends SQLiteException { + public SQLiteDatatypeMismatchException() {} + + public SQLiteDatatypeMismatchException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDebug.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDebug.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import java.util.ArrayList; + +import android.os.Build; +/* import android.os.SystemProperties; */ +import android.util.Log; +import android.util.Printer; + +/** + * Provides debugging info about all SQLite databases running in the current process. + * + * {@hide} + */ +public final class SQLiteDebug { + private static native void nativeGetPagerStats(PagerStats stats); + + /** + * Controls the printing of informational SQL log messages. + * + * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE". + */ + public static final boolean DEBUG_SQL_LOG = + Log.isLoggable("SQLiteLog", Log.VERBOSE); + + /** + * Controls the printing of SQL statements as they are executed. + * + * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE". + */ + public static final boolean DEBUG_SQL_STATEMENTS = + Log.isLoggable("SQLiteStatements", Log.VERBOSE); + + /** + * Controls the printing of wall-clock time taken to execute SQL statements + * as they are executed. + * + * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE". + */ + public static final boolean DEBUG_SQL_TIME = + Log.isLoggable("SQLiteTime", Log.VERBOSE); + + /** + * True to enable database performance testing instrumentation. + * @hide + */ + public static final boolean DEBUG_LOG_SLOW_QUERIES = false; + + private SQLiteDebug() { + } + + /** + * Determines whether a query should be logged. + * + * Reads the "db.log.slow_query_threshold" system property, which can be changed + * by the user at any time. If the value is zero, then all queries will + * be considered slow. If the value does not exist or is negative, then no queries will + * be considered slow. + * + * This value can be changed dynamically while the system is running. + * For example, "adb shell setprop db.log.slow_query_threshold 200" will + * log all queries that take 200ms or longer to run. + * @hide + */ + public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) { + int slowQueryMillis = Integer.parseInt( + System.getProperty("db.log.slow_query_threshold", "10000") + ); + return slowQueryMillis >= 0 && elapsedTimeMillis >= slowQueryMillis; + } + + /** + * Contains statistics about the active pagers in the current process. + * + * @see #nativeGetPagerStats(PagerStats) + */ + public static class PagerStats { + /** the current amount of memory checked out by sqlite using sqlite3_malloc(). + * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html + */ + public int memoryUsed; + + /** the number of bytes of page cache allocation which could not be sattisfied by the + * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc(). + * The returned value includes allocations that overflowed because they where too large + * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations + * that overflowed because no space was left in the page cache. + * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html + */ + public int pageCacheOverflow; + + /** records the largest memory allocation request handed to sqlite3. + * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html + */ + public int largestMemAlloc; + + /** a list of {@link DbStats} - one for each main database opened by the applications + * running on the android device + */ + public ArrayList<DbStats> dbStats; + } + + /** + * contains statistics about a database + */ + public static class DbStats { + /** name of the database */ + public String dbName; + + /** the page size for the database */ + public long pageSize; + + /** the database size */ + public long dbSize; + + /** documented here http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */ + public int lookaside; + + /** statement cache stats: hits/misses/cachesize */ + public String cache; + + public DbStats(String dbName, long pageCount, long pageSize, int lookaside, + int hits, int misses, int cachesize) { + this.dbName = dbName; + this.pageSize = pageSize / 1024; + dbSize = (pageCount * pageSize) / 1024; + this.lookaside = lookaside; + this.cache = hits + "/" + misses + "/" + cachesize; + } + } + + /** + * return all pager and database stats for the current process. + * @return {@link PagerStats} + */ + public static PagerStats getDatabaseInfo() { + PagerStats stats = new PagerStats(); + nativeGetPagerStats(stats); + stats.dbStats = SQLiteDatabase.getDbStats(); + return stats; + } + + /** + * Dumps detailed information about all databases used by the process. + * @param printer The printer for dumping database state. + * @param args Command-line arguments supplied to dumpsys dbinfo + */ + public static void dump(Printer printer, String[] args) { + boolean verbose = false; + for (String arg : args) { + if (arg.equals("-v")) { + verbose = true; + } + } + + SQLiteDatabase.dumpAll(printer, verbose); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDirectCursorDriver.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDirectCursorDriver.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.database.Cursor; +import org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory; +import android.os.CancellationSignal; + +/** + * A cursor driver that uses the given query directly. + * + * @hide + */ +public final class SQLiteDirectCursorDriver implements SQLiteCursorDriver { + private final SQLiteDatabase mDatabase; + private final String mEditTable; + private final String mSql; + private final CancellationSignal mCancellationSignal; + private SQLiteQuery mQuery; + + public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable, + CancellationSignal cancellationSignal) { + mDatabase = db; + mEditTable = editTable; + mSql = sql; + mCancellationSignal = cancellationSignal; + } + + public Cursor query(CursorFactory factory, String[] selectionArgs) { + final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, mCancellationSignal); + final Cursor cursor; + try { + query.bindAllArgsAsStrings(selectionArgs); + + if (factory == null) { + cursor = new SQLiteCursor(this, mEditTable, query); + } else { + cursor = factory.newCursor(mDatabase, this, mEditTable, query); + } + } catch (RuntimeException ex) { + query.close(); + throw ex; + } + + mQuery = query; + return cursor; + } + + public void cursorClosed() { + // Do nothing + } + + public void setBindArguments(String[] bindArgs) { + mQuery.bindAllArgsAsStrings(bindArgs); + } + + public void cursorDeactivated() { + // Do nothing + } + + public void cursorRequeried(Cursor cursor) { + // Do nothing + } + + @Override + public String toString() { + return "SQLiteDirectCursorDriver: " + mSql; + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDiskIOException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDiskIOException.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * An exception that indicates that an IO error occured while accessing the + * SQLite database file. + */ +public class SQLiteDiskIOException extends SQLiteException { + public SQLiteDiskIOException() {} + + public SQLiteDiskIOException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDoneException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteDoneException.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * An exception that indicates that the SQLite program is done. + * Thrown when an operation that expects a row (such as {@link + * SQLiteStatement#simpleQueryForString} or {@link + * SQLiteStatement#simpleQueryForLong}) does not get one. + */ +public class SQLiteDoneException extends SQLiteException { + public SQLiteDoneException() {} + + public SQLiteDoneException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteException.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import org.sqlite.database.SQLException; + +/** + * A SQLite exception that indicates there was an error with SQL parsing or execution. + */ +public class SQLiteException extends SQLException { + public SQLiteException() { + } + + public SQLiteException(String error) { + super(error); + } + + public SQLiteException(String error, Throwable cause) { + super(error, cause); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteFullException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteFullException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * An exception that indicates that the SQLite database is full. + */ +public class SQLiteFullException extends SQLiteException { + public SQLiteFullException() {} + + public SQLiteFullException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteGlobal.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteGlobal.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.content.res.Resources; +import android.os.StatFs; + +/** + * Provides access to SQLite functions that affect all database connection, + * such as memory management. + * + * The native code associated with SQLiteGlobal is also sets global configuration options + * using sqlite3_config() then calls sqlite3_initialize() to ensure that the SQLite + * library is properly initialized exactly once before any other framework or application + * code has a chance to run. + * + * Verbose SQLite logging is enabled if the "log.tag.SQLiteLog" property is set to "V". + * (per {@link SQLiteDebug#DEBUG_SQL_LOG}). + * + * @hide + */ +public final class SQLiteGlobal { + private static final String TAG = "SQLiteGlobal"; + + private static final Object sLock = new Object(); + private static int sDefaultPageSize; + + private static native int nativeReleaseMemory(); + + private SQLiteGlobal() { + } + + /** + * Attempts to release memory by pruning the SQLite page cache and other + * internal data structures. + * + * @return The number of bytes that were freed. + */ + public static int releaseMemory() { + return nativeReleaseMemory(); + } + + /** + * Gets the default page size to use when creating a database. + */ + public static int getDefaultPageSize() { + synchronized (sLock) { + if (sDefaultPageSize == 0) { + // If there is an issue accessing /data, something is so seriously + // wrong that we just let the IllegalArgumentException propagate. + sDefaultPageSize = new StatFs("/data").getBlockSize(); + } + return 1024; + } + } + + /** + * Gets the default journal mode when WAL is not in use. + */ + public static String getDefaultJournalMode() { + return "delete"; + } + + /** + * Gets the journal size limit in bytes. + */ + public static int getJournalSizeLimit() { + return 10000; + } + + /** + * Gets the default database synchronization mode when WAL is not in use. + */ + public static String getDefaultSyncMode() { + return "normal"; + } + + /** + * Gets the database synchronization mode when in WAL mode. + */ + public static String getWALSyncMode() { + return "normal"; + } + + /** + * Gets the WAL auto-checkpoint integer in database pages. + */ + public static int getWALAutoCheckpoint() { + int value = 1000; + return Math.max(1, value); + } + + /** + * Gets the connection pool size when in WAL mode. + */ + public static int getWALConnectionPoolSize() { + int value = 10; + return Math.max(2, value); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteMisuseException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteMisuseException.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * This error can occur if the application creates a SQLiteStatement object and allows multiple + * threads in the application use it at the same time. + * Sqlite returns this error if bind and execute methods on this object occur at the same time + * from multiple threads, like so: + * thread # 1: in execute() method of the SQLiteStatement object + * while thread # 2: is in bind..() on the same object. + *</p> + * FIX this by NEVER sharing the same SQLiteStatement object between threads. + * Create a local instance of the SQLiteStatement whenever it is needed, use it and close it ASAP. + * NEVER make it globally available. + */ +public class SQLiteMisuseException extends SQLiteException { + public SQLiteMisuseException() {} + + public SQLiteMisuseException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteOpenHelper.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteOpenHelper.java @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + + +package org.sqlite.database.sqlite; + +import android.content.Context; +import org.sqlite.database.DatabaseErrorHandler; +import org.sqlite.database.sqlite.SQLiteDatabase.CursorFactory; +import android.util.Log; +import java.io.File; + +/** + * A helper class to manage database creation and version management. + * + * <p>You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and + * optionally {@link #onOpen}, and this class takes care of opening the database + * if it exists, creating it if it does not, and upgrading it as necessary. + * Transactions are used to make sure the database is always in a sensible state. + * + * <p>This class makes it easy for {@link android.content.ContentProvider} + * implementations to defer opening and upgrading the database until first use, + * to avoid blocking application startup with long-running database upgrades. + * + * <p>For an example, see the NotePadProvider class in the NotePad sample application, + * in the <em>samples/</em> directory of the SDK.</p> + * + * <p class="note"><strong>Note:</strong> this class assumes + * monotonically increasing version numbers for upgrades.</p> + */ +public abstract class SQLiteOpenHelper { + private static final String TAG = SQLiteOpenHelper.class.getSimpleName(); + + // When true, getReadableDatabase returns a read-only database if it is just being opened. + // The database handle is reopened in read/write mode when getWritableDatabase is called. + // We leave this behavior disabled in production because it is inefficient and breaks + // many applications. For debugging purposes it can be useful to turn on strict + // read-only semantics to catch applications that call getReadableDatabase when they really + // wanted getWritableDatabase. + private static final boolean DEBUG_STRICT_READONLY = false; + + private final Context mContext; + private final String mName; + private final CursorFactory mFactory; + private final int mNewVersion; + private final int mMinimumSupportedVersion; + + private SQLiteDatabase mDatabase; + private boolean mIsInitializing; + private boolean mEnableWriteAheadLogging; + private final DatabaseErrorHandler mErrorHandler; + + /** + * Create a helper object to create, open, and/or manage a database. + * This method always returns very quickly. The database is not actually + * created or opened until one of {@link #getWritableDatabase} or + * {@link #getReadableDatabase} is called. + * + * @param context to use to open or create the database + * @param name of the database file, or null for an in-memory database + * @param factory to use for creating cursor objects, or null for the default + * @param version number of the database (starting at 1); if the database is older, + * {@link #onUpgrade} will be used to upgrade the database; if the database is + * newer, {@link #onDowngrade} will be used to downgrade the database + */ + public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) { + this(context, name, factory, version, null); + } + + /** + * Create a helper object to create, open, and/or manage a database. + * The database is not actually created or opened until one of + * {@link #getWritableDatabase} or {@link #getReadableDatabase} is called. + * + * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be + * used to handle corruption when sqlite reports database corruption.</p> + * + * @param context to use to open or create the database + * @param name of the database file, or null for an in-memory database + * @param factory to use for creating cursor objects, or null for the default + * @param version number of the database (starting at 1); if the database is older, + * {@link #onUpgrade} will be used to upgrade the database; if the database is + * newer, {@link #onDowngrade} will be used to downgrade the database + * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database + * corruption, or null to use the default error handler. + */ + public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, + DatabaseErrorHandler errorHandler) { + this(context, name, factory, version, 0, errorHandler); + } + + /** + * Same as {@link #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)} + * but also accepts an integer minimumSupportedVersion as a convenience for upgrading very old + * versions of this database that are no longer supported. If a database with older version that + * minimumSupportedVersion is found, it is simply deleted and a new database is created with the + * given name and version + * + * @param context to use to open or create the database + * @param name the name of the database file, null for a temporary in-memory database + * @param factory to use for creating cursor objects, null for default + * @param version the required version of the database + * @param minimumSupportedVersion the minimum version that is supported to be upgraded to + * {@code version} via {@link #onUpgrade}. If the current database version is lower + * than this, database is simply deleted and recreated with the version passed in + * {@code version}. {@link #onBeforeDelete} is called before deleting the database + * when this happens. This is 0 by default. + * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database + * corruption, or null to use the default error handler. + * @see #onBeforeDelete(SQLiteDatabase) + * @see #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler) + * @see #onUpgrade(SQLiteDatabase, int, int) + * @hide + */ + public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, + int minimumSupportedVersion, DatabaseErrorHandler errorHandler) { + if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version); + + mContext = context; + mName = name; + mFactory = factory; + mNewVersion = version; + mErrorHandler = errorHandler; + mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion); + } + + /** + * Return the name of the SQLite database being opened, as given to + * the constructor. + */ + public String getDatabaseName() { + return mName; + } + + /** + * Enables or disables the use of write-ahead logging for the database. + * + * Write-ahead logging cannot be used with read-only databases so the value of + * this flag is ignored if the database is opened read-only. + * + * @param enabled True if write-ahead logging should be enabled, false if it + * should be disabled. + * + * @see SQLiteDatabase#enableWriteAheadLogging() + */ + public void setWriteAheadLoggingEnabled(boolean enabled) { + synchronized (this) { + if (mEnableWriteAheadLogging != enabled) { + if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) { + if (enabled) { + mDatabase.enableWriteAheadLogging(); + } else { + mDatabase.disableWriteAheadLogging(); + } + } + mEnableWriteAheadLogging = enabled; + } + } + } + + /** + * Create and/or open a database that will be used for reading and writing. + * The first time this is called, the database will be opened and + * {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be + * called. + * + * <p>Once opened successfully, the database is cached, so you can + * call this method every time you need to write to the database. + * (Make sure to call {@link #close} when you no longer need the database.) + * Errors such as bad permissions or a full disk may cause this method + * to fail, but future attempts may succeed if the problem is fixed.</p> + * + * <p class="caution">Database upgrade may take a long time, you + * should not call this method from the application main thread, including + * from {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}. + * + * @throws SQLiteException if the database cannot be opened for writing + * @return a read/write database object valid until {@link #close} is called + */ + public SQLiteDatabase getWritableDatabase() { + synchronized (this) { + return getDatabaseLocked(true); + } + } + + /** + * Create and/or open a database. This will be the same object returned by + * {@link #getWritableDatabase} unless some problem, such as a full disk, + * requires the database to be opened read-only. In that case, a read-only + * database object will be returned. If the problem is fixed, a future call + * to {@link #getWritableDatabase} may succeed, in which case the read-only + * database object will be closed and the read/write object will be returned + * in the future. + * + * <p class="caution">Like {@link #getWritableDatabase}, this method may + * take a long time to return, so you should not call it from the + * application main thread, including from + * {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}. + * + * @throws SQLiteException if the database cannot be opened + * @return a database object valid until {@link #getWritableDatabase} + * or {@link #close} is called. + */ + public SQLiteDatabase getReadableDatabase() { + synchronized (this) { + return getDatabaseLocked(false); + } + } + + private SQLiteDatabase getDatabaseLocked(boolean writable) { + if (mDatabase != null) { + if (!mDatabase.isOpen()) { + // Darn! The user closed the database by calling mDatabase.close(). + mDatabase = null; + } else if (!writable || !mDatabase.isReadOnly()) { + // The database is already open for business. + return mDatabase; + } + } + + if (mIsInitializing) { + throw new IllegalStateException("getDatabase called recursively"); + } + + SQLiteDatabase db = mDatabase; + try { + mIsInitializing = true; + + if (db != null) { + if (writable && db.isReadOnly()) { + db.reopenReadWrite(); + } + } else if (mName == null) { + db = SQLiteDatabase.create(null); + } else { + String path = mName; + if (!path.startsWith("file:")) { + path = mContext.getDatabasePath(path).getPath(); + } + try { + if (DEBUG_STRICT_READONLY && !writable) { + db = SQLiteDatabase.openDatabase(path, mFactory, + SQLiteDatabase.OPEN_READONLY, mErrorHandler); + } else { + db = SQLiteDatabase.openOrCreateDatabase( + path, mFactory, mErrorHandler + ); + } + } catch (SQLiteException ex) { + if (writable) { + throw ex; + } + Log.e(TAG, "Couldn't open " + mName + + " for writing (will try read-only):", ex); + db = SQLiteDatabase.openDatabase(path, mFactory, + SQLiteDatabase.OPEN_READONLY, mErrorHandler); + } + } + + onConfigure(db); + + final int version = db.getVersion(); + if (version != mNewVersion) { + if (db.isReadOnly()) { + throw new SQLiteException("Can't upgrade read-only database from version " + + db.getVersion() + " to " + mNewVersion + ": " + mName); + } + + if (version > 0 && version < mMinimumSupportedVersion) { + File databaseFile = new File(db.getPath()); + onBeforeDelete(db); + db.close(); + if (SQLiteDatabase.deleteDatabase(databaseFile)) { + mIsInitializing = false; + return getDatabaseLocked(writable); + } else { + throw new IllegalStateException("Unable to delete obsolete database " + + mName + " with version " + version); + } + } else { + db.beginTransaction(); + try { + if (version == 0) { + onCreate(db); + } else { + if (version > mNewVersion) { + onDowngrade(db, version, mNewVersion); + } else { + onUpgrade(db, version, mNewVersion); + } + } + db.setVersion(mNewVersion); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + } + + onOpen(db); + + if (db.isReadOnly()) { + Log.w(TAG, "Opened " + mName + " in read-only mode"); + } + + mDatabase = db; + return db; + } finally { + mIsInitializing = false; + if (db != null && db != mDatabase) { + db.close(); + } + } + } + + /** + * Close any open database object. + */ + public synchronized void close() { + if (mIsInitializing) throw new IllegalStateException("Closed during initialization"); + + if (mDatabase != null && mDatabase.isOpen()) { + mDatabase.close(); + mDatabase = null; + } + } + + /** + * Called when the database connection is being configured, to enable features such as + * write-ahead logging or foreign key support. + * <p> + * This method is called before {@link #onCreate}, {@link #onUpgrade}, {@link #onDowngrade}, or + * {@link #onOpen} are called. It should not modify the database except to configure the + * database connection as required. + * </p> + * <p> + * This method should only call methods that configure the parameters of the database + * connection, such as {@link SQLiteDatabase#enableWriteAheadLogging} + * {@link SQLiteDatabase#setForeignKeyConstraintsEnabled}, {@link SQLiteDatabase#setLocale}, + * {@link SQLiteDatabase#setMaximumSize}, or executing PRAGMA statements. + * </p> + * + * @param db The database. + */ + public void onConfigure(SQLiteDatabase db) {} + + /** + * Called before the database is deleted when the version returned by + * {@link SQLiteDatabase#getVersion()} is lower than the minimum supported version passed (if at + * all) while creating this helper. After the database is deleted, a fresh database with the + * given version is created. This will be followed by {@link #onConfigure(SQLiteDatabase)} and + * {@link #onCreate(SQLiteDatabase)} being called with a new SQLiteDatabase object + * + * @param db the database opened with this helper + * @see #SQLiteOpenHelper(Context, String, CursorFactory, int, int, DatabaseErrorHandler) + * @hide + */ + public void onBeforeDelete(SQLiteDatabase db) { + } + + /** + * Called when the database is created for the first time. This is where the + * creation of tables and the initial population of the tables should happen. + * + * @param db The database. + */ + public abstract void onCreate(SQLiteDatabase db); + + /** + * Called when the database needs to be upgraded. The implementation + * should use this method to drop tables, add tables, or do anything else it + * needs to upgrade to the new schema version. + * + * <p> + * The SQLite ALTER TABLE documentation can be found + * <a href="http://sqlite.org/lang_altertable.html">here</a>. If you add new columns + * you can use ALTER TABLE to insert them into a live table. If you rename or remove columns + * you can use ALTER TABLE to rename the old table, then create the new table and then + * populate the new table with the contents of the old table. + * </p><p> + * This method executes within a transaction. If an exception is thrown, all changes + * will automatically be rolled back. + * </p> + * + * @param db The database. + * @param oldVersion The old database version. + * @param newVersion The new database version. + */ + public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion); + + /** + * Called when the database needs to be downgraded. This is strictly similar to + * {@link #onUpgrade} method, but is called whenever current version is newer than requested one. + * However, this method is not abstract, so it is not mandatory for a customer to + * implement it. If not overridden, default implementation will reject downgrade and + * throws SQLiteException + * + * <p> + * This method executes within a transaction. If an exception is thrown, all changes + * will automatically be rolled back. + * </p> + * + * @param db The database. + * @param oldVersion The old database version. + * @param newVersion The new database version. + */ + public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { + throw new SQLiteException("Can't downgrade database from version " + + oldVersion + " to " + newVersion); + } + + /** + * Called when the database has been opened. The implementation + * should check {@link SQLiteDatabase#isReadOnly} before updating the + * database. + * <p> + * This method is called after the database connection has been configured + * and after the database schema has been created, upgraded or downgraded as necessary. + * If the database connection must be configured in some way before the schema + * is created, upgraded, or downgraded, do it in {@link #onConfigure} instead. + * </p> + * + * @param db The database. + */ + public void onOpen(SQLiteDatabase db) {} +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteOutOfMemoryException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteOutOfMemoryException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +public class SQLiteOutOfMemoryException extends SQLiteException { + public SQLiteOutOfMemoryException() {} + + public SQLiteOutOfMemoryException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteProgram.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteProgram.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.database.DatabaseUtils; +import android.os.CancellationSignal; + +import java.util.Arrays; + +/** + * A base class for compiled SQLite programs. + * <p> + * This class is not thread-safe. + * </p> + */ +public abstract class SQLiteProgram extends SQLiteClosable { + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + private final SQLiteDatabase mDatabase; + private final String mSql; + private final boolean mReadOnly; + private final String[] mColumnNames; + private final int mNumParameters; + private final Object[] mBindArgs; + + SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs, + CancellationSignal cancellationSignalForPrepare) { + mDatabase = db; + mSql = sql.trim(); + + int n = DatabaseUtils.getSqlStatementType(mSql); + switch (n) { + case DatabaseUtils.STATEMENT_BEGIN: + case DatabaseUtils.STATEMENT_COMMIT: + case DatabaseUtils.STATEMENT_ABORT: + mReadOnly = false; + mColumnNames = EMPTY_STRING_ARRAY; + mNumParameters = 0; + break; + + default: + boolean assumeReadOnly = (n == DatabaseUtils.STATEMENT_SELECT); + SQLiteStatementInfo info = new SQLiteStatementInfo(); + db.getThreadSession().prepare(mSql, + db.getThreadDefaultConnectionFlags(assumeReadOnly), + cancellationSignalForPrepare, info); + mReadOnly = info.readOnly; + mColumnNames = info.columnNames; + mNumParameters = info.numParameters; + break; + } + + if (bindArgs != null && bindArgs.length > mNumParameters) { + throw new IllegalArgumentException("Too many bind arguments. " + + bindArgs.length + " arguments were provided but the statement needs " + + mNumParameters + " arguments."); + } + + if (mNumParameters != 0) { + mBindArgs = new Object[mNumParameters]; + if (bindArgs != null) { + System.arraycopy(bindArgs, 0, mBindArgs, 0, bindArgs.length); + } + } else { + mBindArgs = null; + } + } + + final SQLiteDatabase getDatabase() { + return mDatabase; + } + + final String getSql() { + return mSql; + } + + final Object[] getBindArgs() { + return mBindArgs; + } + + final String[] getColumnNames() { + return mColumnNames; + } + + /** @hide */ + protected final SQLiteSession getSession() { + return mDatabase.getThreadSession(); + } + + /** @hide */ + protected final int getConnectionFlags() { + return mDatabase.getThreadDefaultConnectionFlags(mReadOnly); + } + + /** @hide */ + protected final void onCorruption() { + mDatabase.onCorruption(); + } + + /** + * Unimplemented. + * @deprecated This method is deprecated and must not be used. + */ + @Deprecated + public final int getUniqueId() { + return -1; + } + + /** + * Bind a NULL value to this statement. The value remains bound until + * {@link #clearBindings} is called. + * + * @param index The 1-based index to the parameter to bind null to + */ + public void bindNull(int index) { + bind(index, null); + } + + /** + * Bind a long value to this statement. The value remains bound until + * {@link #clearBindings} is called. + *addToBindArgs + * @param index The 1-based index to the parameter to bind + * @param value The value to bind + */ + public void bindLong(int index, long value) { + bind(index, value); + } + + /** + * Bind a double value to this statement. The value remains bound until + * {@link #clearBindings} is called. + * + * @param index The 1-based index to the parameter to bind + * @param value The value to bind + */ + public void bindDouble(int index, double value) { + bind(index, value); + } + + /** + * Bind a String value to this statement. The value remains bound until + * {@link #clearBindings} is called. + * + * @param index The 1-based index to the parameter to bind + * @param value The value to bind, must not be null + */ + public void bindString(int index, String value) { + if (value == null) { + throw new IllegalArgumentException("the bind value at index " + index + " is null"); + } + bind(index, value); + } + + /** + * Bind a byte array value to this statement. The value remains bound until + * {@link #clearBindings} is called. + * + * @param index The 1-based index to the parameter to bind + * @param value The value to bind, must not be null + */ + public void bindBlob(int index, byte[] value) { + if (value == null) { + throw new IllegalArgumentException("the bind value at index " + index + " is null"); + } + bind(index, value); + } + + /** + * Clears all existing bindings. Unset bindings are treated as NULL. + */ + public void clearBindings() { + if (mBindArgs != null) { + Arrays.fill(mBindArgs, null); + } + } + + /** + * Given an array of String bindArgs, this method binds all of them in one single call. + * + * @param bindArgs the String array of bind args, none of which must be null. + */ + public void bindAllArgsAsStrings(String[] bindArgs) { + if (bindArgs != null) { + for (int i = bindArgs.length; i != 0; i--) { + bindString(i, bindArgs[i - 1]); + } + } + } + + @Override + protected void onAllReferencesReleased() { + clearBindings(); + } + + private void bind(int index, Object value) { + if (index < 1 || index > mNumParameters) { + throw new IllegalArgumentException("Cannot bind argument at index " + + index + " because the index is out of range. " + + "The statement has " + mNumParameters + " parameters."); + } + mBindArgs[index - 1] = value; + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteQuery.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteQuery.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.database.CursorWindow; +import android.os.CancellationSignal; +import android.os.OperationCanceledException; +import android.util.Log; + +/** + * Represents a query that reads the resulting rows into a {@link SQLiteQuery}. + * This class is used by {@link SQLiteCursor} and isn't useful itself. + * <p> + * This class is not thread-safe. + * </p> + */ +public final class SQLiteQuery extends SQLiteProgram { + private static final String TAG = "SQLiteQuery"; + + private final CancellationSignal mCancellationSignal; + + SQLiteQuery(SQLiteDatabase db, String query, CancellationSignal cancellationSignal) { + super(db, query, null, cancellationSignal); + + mCancellationSignal = cancellationSignal; + } + + /** + * Reads rows into a buffer. + * + * @param window The window to fill into + * @param startPos The start position for filling the window. + * @param requiredPos The position of a row that MUST be in the window. + * If it won't fit, then the query should discard part of what it filled. + * @param countAllRows True to count all rows that the query would + * return regardless of whether they fit in the window. + * @return Number of rows that were enumerated. Might not be all rows + * unless countAllRows is true. + * + * @throws SQLiteException if an error occurs. + * @throws OperationCanceledException if the operation was canceled. + */ + int fillWindow(CursorWindow window, int startPos, int requiredPos, boolean countAllRows) { + acquireReference(); + try { + window.acquireReference(); + try { + int numRows = getSession().executeForCursorWindow(getSql(), getBindArgs(), + window, startPos, requiredPos, countAllRows, getConnectionFlags(), + mCancellationSignal); + return numRows; + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + throw ex; + } catch (SQLiteException ex) { + Log.e(TAG, "exception: " + ex.getMessage() + "; query: " + getSql()); + throw ex; + } finally { + window.releaseReference(); + } + } finally { + releaseReference(); + } + } + + @Override + public String toString() { + return "SQLiteQuery: " + getSql(); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteQueryBuilder.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteQueryBuilder.java @@ -0,0 +1,652 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.database.Cursor; +import android.database.DatabaseUtils; +import android.os.CancellationSignal; +import android.os.OperationCanceledException; +import android.provider.BaseColumns; +import android.text.TextUtils; +import android.util.Log; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * This is a convience class that helps build SQL queries to be sent to + * {@link SQLiteDatabase} objects. + */ +public class SQLiteQueryBuilder +{ + private static final String TAG = "SQLiteQueryBuilder"; + private static final Pattern sLimitPattern = + Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?"); + + private Map<String, String> mProjectionMap = null; + private String mTables = ""; + private StringBuilder mWhereClause = null; // lazily created + private boolean mDistinct; + private SQLiteDatabase.CursorFactory mFactory; + private boolean mStrict; + + public SQLiteQueryBuilder() { + mDistinct = false; + mFactory = null; + } + + /** + * Mark the query as DISTINCT. + * + * @param distinct if true the query is DISTINCT, otherwise it isn't + */ + public void setDistinct(boolean distinct) { + mDistinct = distinct; + } + + /** + * Returns the list of tables being queried + * + * @return the list of tables being queried + */ + public String getTables() { + return mTables; + } + + /** + * Sets the list of tables to query. Multiple tables can be specified to perform a join. + * For example: + * setTables("foo, bar") + * setTables("foo LEFT OUTER JOIN bar ON (foo.id = bar.foo_id)") + * + * @param inTables the list of tables to query on + */ + public void setTables(String inTables) { + mTables = inTables; + } + + /** + * Append a chunk to the WHERE clause of the query. All chunks appended are surrounded + * by parenthesis and ANDed with the selection passed to {@link #query}. The final + * WHERE clause looks like: + * + * WHERE (<append chunk 1><append chunk2>) AND (<query() selection parameter>) + * + * @param inWhere the chunk of text to append to the WHERE clause. + */ + public void appendWhere(CharSequence inWhere) { + if (mWhereClause == null) { + mWhereClause = new StringBuilder(inWhere.length() + 16); + } + if (mWhereClause.length() == 0) { + mWhereClause.append('('); + } + mWhereClause.append(inWhere); + } + + /** + * Append a chunk to the WHERE clause of the query. All chunks appended are surrounded + * by parenthesis and ANDed with the selection passed to {@link #query}. The final + * WHERE clause looks like: + * + * WHERE (<append chunk 1><append chunk2>) AND (<query() selection parameter>) + * + * @param inWhere the chunk of text to append to the WHERE clause. it will be escaped + * to avoid SQL injection attacks + */ + public void appendWhereEscapeString(String inWhere) { + if (mWhereClause == null) { + mWhereClause = new StringBuilder(inWhere.length() + 16); + } + if (mWhereClause.length() == 0) { + mWhereClause.append('('); + } + DatabaseUtils.appendEscapedSQLString(mWhereClause, inWhere); + } + + /** + * Sets the projection map for the query. The projection map maps + * from column names that the caller passes into query to database + * column names. This is useful for renaming columns as well as + * disambiguating column names when doing joins. For example you + * could map "name" to "people.name". If a projection map is set + * it must contain all column names the user may request, even if + * the key and value are the same. + * + * @param columnMap maps from the user column names to the database column names + */ + public void setProjectionMap(Map<String, String> columnMap) { + mProjectionMap = columnMap; + } + + /** + * Sets the cursor factory to be used for the query. You can use + * one factory for all queries on a database but it is normally + * easier to specify the factory when doing this query. + * + * @param factory the factory to use. + */ + public void setCursorFactory(SQLiteDatabase.CursorFactory factory) { + mFactory = factory; + } + + /** + * When set, the selection is verified against malicious arguments. + * When using this class to create a statement using + * {@link #buildQueryString(boolean, String, String[], String, String, String, String, String)}, + * non-numeric limits will raise an exception. If a projection map is specified, fields + * not in that map will be ignored. + * If this class is used to execute the statement directly using + * {@link #query(SQLiteDatabase, String[], String, String[], String, String, String)} + * or + * {@link #query(SQLiteDatabase, String[], String, String[], String, String, String, String)}, + * additionally also parenthesis escaping selection are caught. + * + * To summarize: To get maximum protection against malicious third party apps (for example + * content provider consumers), make sure to do the following: + * <ul> + * <li>Set this value to true</li> + * <li>Use a projection map</li> + * <li>Use one of the query overloads instead of getting the statement as a sql string</li> + * </ul> + * By default, this value is false. + */ + public void setStrict(boolean flag) { + mStrict = flag; + } + + /** + * Build an SQL query string from the given clauses. + * + * @param distinct true if you want each row to be unique, false otherwise. + * @param tables The table names to compile the query against. + * @param columns A list of which columns to return. Passing null will + * return all columns, which is discouraged to prevent reading + * data from storage that isn't going to be used. + * @param where A filter declaring which rows to return, formatted as an SQL + * WHERE clause (excluding the WHERE itself). Passing null will + * return all rows for the given URL. + * @param groupBy A filter declaring how to group rows, formatted as an SQL + * GROUP BY clause (excluding the GROUP BY itself). Passing null + * will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in the cursor, + * if row grouping is being used, formatted as an SQL HAVING + * clause (excluding the HAVING itself). Passing null will cause + * all row groups to be included, and is required when row + * grouping is not being used. + * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause + * (excluding the ORDER BY itself). Passing null will use the + * default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @return the SQL query string + */ + public static String buildQueryString( + boolean distinct, String tables, String[] columns, String where, + String groupBy, String having, String orderBy, String limit) { + if (TextUtils.isEmpty(groupBy) && !TextUtils.isEmpty(having)) { + throw new IllegalArgumentException( + "HAVING clauses are only permitted when using a groupBy clause"); + } + if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) { + throw new IllegalArgumentException("invalid LIMIT clauses:" + limit); + } + + StringBuilder query = new StringBuilder(120); + + query.append("SELECT "); + if (distinct) { + query.append("DISTINCT "); + } + if (columns != null && columns.length != 0) { + appendColumns(query, columns); + } else { + query.append("* "); + } + query.append("FROM "); + query.append(tables); + appendClause(query, " WHERE ", where); + appendClause(query, " GROUP BY ", groupBy); + appendClause(query, " HAVING ", having); + appendClause(query, " ORDER BY ", orderBy); + appendClause(query, " LIMIT ", limit); + + return query.toString(); + } + + private static void appendClause(StringBuilder s, String name, String clause) { + if (!TextUtils.isEmpty(clause)) { + s.append(name); + s.append(clause); + } + } + + /** + * Add the names that are non-null in columns to s, separating + * them with commas. + */ + public static void appendColumns(StringBuilder s, String[] columns) { + int n = columns.length; + + for (int i = 0; i < n; i++) { + String column = columns[i]; + + if (column != null) { + if (i > 0) { + s.append(", "); + } + s.append(column); + } + } + s.append(' '); + } + + /** + * Perform a query by combining all current settings and the + * information passed into this method. + * + * @param db the database to query on + * @param projectionIn A list of which columns to return. Passing + * null will return all columns, which is discouraged to prevent + * reading data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, + * formatted as an SQL WHERE clause (excluding the WHERE + * itself). Passing null will return all rows for the given URL. + * @param selectionArgs You may include ?s in selection, which + * will be replaced by the values from selectionArgs, in order + * that they appear in the selection. The values will be bound + * as Strings. + * @param groupBy A filter declaring how to group rows, formatted + * as an SQL GROUP BY clause (excluding the GROUP BY + * itself). Passing null will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in + * the cursor, if row grouping is being used, formatted as an + * SQL HAVING clause (excluding the HAVING itself). Passing + * null will cause all row groups to be included, and is + * required when row grouping is not being used. + * @param sortOrder How to order the rows, formatted as an SQL + * ORDER BY clause (excluding the ORDER BY itself). Passing null + * will use the default sort order, which may be unordered. + * @return a cursor over the result set + * @see android.content.ContentResolver#query(android.net.Uri, String[], + * String, String[], String) + */ + public Cursor query(SQLiteDatabase db, String[] projectionIn, + String selection, String[] selectionArgs, String groupBy, + String having, String sortOrder) { + return query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder, + null /* limit */, null /* cancellationSignal */); + } + + /** + * Perform a query by combining all current settings and the + * information passed into this method. + * + * @param db the database to query on + * @param projectionIn A list of which columns to return. Passing + * null will return all columns, which is discouraged to prevent + * reading data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, + * formatted as an SQL WHERE clause (excluding the WHERE + * itself). Passing null will return all rows for the given URL. + * @param selectionArgs You may include ?s in selection, which + * will be replaced by the values from selectionArgs, in order + * that they appear in the selection. The values will be bound + * as Strings. + * @param groupBy A filter declaring how to group rows, formatted + * as an SQL GROUP BY clause (excluding the GROUP BY + * itself). Passing null will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in + * the cursor, if row grouping is being used, formatted as an + * SQL HAVING clause (excluding the HAVING itself). Passing + * null will cause all row groups to be included, and is + * required when row grouping is not being used. + * @param sortOrder How to order the rows, formatted as an SQL + * ORDER BY clause (excluding the ORDER BY itself). Passing null + * will use the default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @return a cursor over the result set + * @see android.content.ContentResolver#query(android.net.Uri, String[], + * String, String[], String) + */ + public Cursor query(SQLiteDatabase db, String[] projectionIn, + String selection, String[] selectionArgs, String groupBy, + String having, String sortOrder, String limit) { + return query(db, projectionIn, selection, selectionArgs, + groupBy, having, sortOrder, limit, null); + } + + /** + * Perform a query by combining all current settings and the + * information passed into this method. + * + * @param db the database to query on + * @param projectionIn A list of which columns to return. Passing + * null will return all columns, which is discouraged to prevent + * reading data from storage that isn't going to be used. + * @param selection A filter declaring which rows to return, + * formatted as an SQL WHERE clause (excluding the WHERE + * itself). Passing null will return all rows for the given URL. + * @param selectionArgs You may include ?s in selection, which + * will be replaced by the values from selectionArgs, in order + * that they appear in the selection. The values will be bound + * as Strings. + * @param groupBy A filter declaring how to group rows, formatted + * as an SQL GROUP BY clause (excluding the GROUP BY + * itself). Passing null will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in + * the cursor, if row grouping is being used, formatted as an + * SQL HAVING clause (excluding the HAVING itself). Passing + * null will cause all row groups to be included, and is + * required when row grouping is not being used. + * @param sortOrder How to order the rows, formatted as an SQL + * ORDER BY clause (excluding the ORDER BY itself). Passing null + * will use the default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * If the operation is canceled, then {@link OperationCanceledException} will be thrown + * when the query is executed. + * @return a cursor over the result set + * @see android.content.ContentResolver#query(android.net.Uri, String[], + * String, String[], String) + */ + public Cursor query(SQLiteDatabase db, String[] projectionIn, + String selection, String[] selectionArgs, String groupBy, + String having, String sortOrder, String limit, CancellationSignal cancellationSignal) { + if (mTables == null) { + return null; + } + + if (mStrict && selection != null && selection.length() > 0) { + // Validate the user-supplied selection to detect syntactic anomalies + // in the selection string that could indicate a SQL injection attempt. + // The idea is to ensure that the selection clause is a valid SQL expression + // by compiling it twice: once wrapped in parentheses and once as + // originally specified. An attacker cannot create an expression that + // would escape the SQL expression while maintaining balanced parentheses + // in both the wrapped and original forms. + String sqlForValidation = buildQuery(projectionIn, "(" + selection + ")", groupBy, + having, sortOrder, limit); + db.validateSql(sqlForValidation, cancellationSignal); // will throw if query is invalid + } + + String sql = buildQuery( + projectionIn, selection, groupBy, having, + sortOrder, limit); + + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Performing query: " + sql); + } + return db.rawQueryWithFactory( + mFactory, sql, selectionArgs, + SQLiteDatabase.findEditTable(mTables), + cancellationSignal); // will throw if query is invalid + } + + /** + * Construct a SELECT statement suitable for use in a group of + * SELECT statements that will be joined through UNION operators + * in buildUnionQuery. + * + * @param projectionIn A list of which columns to return. Passing + * null will return all columns, which is discouraged to + * prevent reading data from storage that isn't going to be + * used. + * @param selection A filter declaring which rows to return, + * formatted as an SQL WHERE clause (excluding the WHERE + * itself). Passing null will return all rows for the given + * URL. + * @param groupBy A filter declaring how to group rows, formatted + * as an SQL GROUP BY clause (excluding the GROUP BY itself). + * Passing null will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in + * the cursor, if row grouping is being used, formatted as an + * SQL HAVING clause (excluding the HAVING itself). Passing + * null will cause all row groups to be included, and is + * required when row grouping is not being used. + * @param sortOrder How to order the rows, formatted as an SQL + * ORDER BY clause (excluding the ORDER BY itself). Passing null + * will use the default sort order, which may be unordered. + * @param limit Limits the number of rows returned by the query, + * formatted as LIMIT clause. Passing null denotes no LIMIT clause. + * @return the resulting SQL SELECT statement + */ + public String buildQuery( + String[] projectionIn, String selection, String groupBy, + String having, String sortOrder, String limit) { + String[] projection = computeProjection(projectionIn); + + StringBuilder where = new StringBuilder(); + boolean hasBaseWhereClause = mWhereClause != null && mWhereClause.length() > 0; + + if (hasBaseWhereClause) { + where.append(mWhereClause.toString()); + where.append(')'); + } + + // Tack on the user's selection, if present. + if (selection != null && selection.length() > 0) { + if (hasBaseWhereClause) { + where.append(" AND "); + } + + where.append('('); + where.append(selection); + where.append(')'); + } + + return buildQueryString( + mDistinct, mTables, projection, where.toString(), + groupBy, having, sortOrder, limit); + } + + /** + * @deprecated This method's signature is misleading since no SQL parameter + * substitution is carried out. The selection arguments parameter does not get + * used at all. To avoid confusion, call + * {@link #buildQuery(String[], String, String, String, String, String)} instead. + */ + @Deprecated + public String buildQuery( + String[] projectionIn, String selection, String[] selectionArgs, + String groupBy, String having, String sortOrder, String limit) { + return buildQuery(projectionIn, selection, groupBy, having, sortOrder, limit); + } + + /** + * Construct a SELECT statement suitable for use in a group of + * SELECT statements that will be joined through UNION operators + * in buildUnionQuery. + * + * @param typeDiscriminatorColumn the name of the result column + * whose cells will contain the name of the table from which + * each row was drawn. + * @param unionColumns the names of the columns to appear in the + * result. This may include columns that do not appear in the + * table this SELECT is querying (i.e. mTables), but that do + * appear in one of the other tables in the UNION query that we + * are constructing. + * @param columnsPresentInTable a Set of the names of the columns + * that appear in this table (i.e. in the table whose name is + * mTables). Since columns in unionColumns include columns that + * appear only in other tables, we use this array to distinguish + * which ones actually are present. Other columns will have + * NULL values for results from this subquery. + * @param computedColumnsOffset all columns in unionColumns before + * this index are included under the assumption that they're + * computed and therefore won't appear in columnsPresentInTable, + * e.g. "date * 1000 as normalized_date" + * @param typeDiscriminatorValue the value used for the + * type-discriminator column in this subquery + * @param selection A filter declaring which rows to return, + * formatted as an SQL WHERE clause (excluding the WHERE + * itself). Passing null will return all rows for the given + * URL. + * @param groupBy A filter declaring how to group rows, formatted + * as an SQL GROUP BY clause (excluding the GROUP BY itself). + * Passing null will cause the rows to not be grouped. + * @param having A filter declare which row groups to include in + * the cursor, if row grouping is being used, formatted as an + * SQL HAVING clause (excluding the HAVING itself). Passing + * null will cause all row groups to be included, and is + * required when row grouping is not being used. + * @return the resulting SQL SELECT statement + */ + public String buildUnionSubQuery( + String typeDiscriminatorColumn, + String[] unionColumns, + Set<String> columnsPresentInTable, + int computedColumnsOffset, + String typeDiscriminatorValue, + String selection, + String groupBy, + String having) { + int unionColumnsCount = unionColumns.length; + String[] projectionIn = new String[unionColumnsCount]; + + for (int i = 0; i < unionColumnsCount; i++) { + String unionColumn = unionColumns[i]; + + if (unionColumn.equals(typeDiscriminatorColumn)) { + projectionIn[i] = "'" + typeDiscriminatorValue + "' AS " + + typeDiscriminatorColumn; + } else if (i <= computedColumnsOffset + || columnsPresentInTable.contains(unionColumn)) { + projectionIn[i] = unionColumn; + } else { + projectionIn[i] = "NULL AS " + unionColumn; + } + } + return buildQuery( + projectionIn, selection, groupBy, having, + null /* sortOrder */, + null /* limit */); + } + + /** + * @deprecated This method's signature is misleading since no SQL parameter + * substitution is carried out. The selection arguments parameter does not get + * used at all. To avoid confusion, call + * {@link #buildUnionSubQuery} + * instead. + */ + @Deprecated + public String buildUnionSubQuery( + String typeDiscriminatorColumn, + String[] unionColumns, + Set<String> columnsPresentInTable, + int computedColumnsOffset, + String typeDiscriminatorValue, + String selection, + String[] selectionArgs, + String groupBy, + String having) { + return buildUnionSubQuery( + typeDiscriminatorColumn, unionColumns, columnsPresentInTable, + computedColumnsOffset, typeDiscriminatorValue, selection, + groupBy, having); + } + + /** + * Given a set of subqueries, all of which are SELECT statements, + * construct a query that returns the union of what those + * subqueries return. + * @param subQueries an array of SQL SELECT statements, all of + * which must have the same columns as the same positions in + * their results + * @param sortOrder How to order the rows, formatted as an SQL + * ORDER BY clause (excluding the ORDER BY itself). Passing + * null will use the default sort order, which may be unordered. + * @param limit The limit clause, which applies to the entire union result set + * + * @return the resulting SQL SELECT statement + */ + public String buildUnionQuery(String[] subQueries, String sortOrder, String limit) { + StringBuilder query = new StringBuilder(128); + int subQueryCount = subQueries.length; + String unionOperator = mDistinct ? " UNION " : " UNION ALL "; + + for (int i = 0; i < subQueryCount; i++) { + if (i > 0) { + query.append(unionOperator); + } + query.append(subQueries[i]); + } + appendClause(query, " ORDER BY ", sortOrder); + appendClause(query, " LIMIT ", limit); + return query.toString(); + } + + private String[] computeProjection(String[] projectionIn) { + if (projectionIn != null && projectionIn.length > 0) { + if (mProjectionMap != null) { + String[] projection = new String[projectionIn.length]; + int length = projectionIn.length; + + for (int i = 0; i < length; i++) { + String userColumn = projectionIn[i]; + String column = mProjectionMap.get(userColumn); + + if (column != null) { + projection[i] = column; + continue; + } + + if (!mStrict && + ( userColumn.contains(" AS ") || userColumn.contains(" as "))) { + /* A column alias already exist */ + projection[i] = userColumn; + continue; + } + + throw new IllegalArgumentException("Invalid column " + + projectionIn[i]); + } + return projection; + } else { + return projectionIn; + } + } else if (mProjectionMap != null) { + // Return all columns in projection map. + Set<Entry<String, String>> entrySet = mProjectionMap.entrySet(); + String[] projection = new String[entrySet.size()]; + Iterator<Entry<String, String>> entryIter = entrySet.iterator(); + int i = 0; + + while (entryIter.hasNext()) { + Entry<String, String> entry = entryIter.next(); + + // Don't include the _count column when people ask for no projection. + if (entry.getKey().equals(BaseColumns._COUNT)) { + continue; + } + projection[i++] = entry.getValue(); + } + return projection; + } + return null; + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteReadOnlyDatabaseException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteReadOnlyDatabaseException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +public class SQLiteReadOnlyDatabaseException extends SQLiteException { + public SQLiteReadOnlyDatabaseException() {} + + public SQLiteReadOnlyDatabaseException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteSession.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteSession.java @@ -0,0 +1,967 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.database.CursorWindow; +import android.database.DatabaseUtils; +import android.os.CancellationSignal; +import android.os.OperationCanceledException; +import android.os.ParcelFileDescriptor; + +/** + * Provides a single client the ability to use a database. + * + * <h2>About database sessions</h2> + * <p> + * Database access is always performed using a session. The session + * manages the lifecycle of transactions and database connections. + * </p><p> + * Sessions can be used to perform both read-only and read-write operations. + * There is some advantage to knowing when a session is being used for + * read-only purposes because the connection pool can optimize the use + * of the available connections to permit multiple read-only operations + * to execute in parallel whereas read-write operations may need to be serialized. + * </p><p> + * When <em>Write Ahead Logging (WAL)</em> is enabled, the database can + * execute simultaneous read-only and read-write transactions, provided that + * at most one read-write transaction is performed at a time. When WAL is not + * enabled, read-only transactions can execute in parallel but read-write + * transactions are mutually exclusive. + * </p> + * + * <h2>Ownership and concurrency guarantees</h2> + * <p> + * Session objects are not thread-safe. In fact, session objects are thread-bound. + * The {@link SQLiteDatabase} uses a thread-local variable to associate a session + * with each thread for the use of that thread alone. Consequently, each thread + * has its own session object and therefore its own transaction state independent + * of other threads. + * </p><p> + * A thread has at most one session per database. This constraint ensures that + * a thread can never use more than one database connection at a time for a + * given database. As the number of available database connections is limited, + * if a single thread tried to acquire multiple connections for the same database + * at the same time, it might deadlock. Therefore we allow there to be only + * one session (so, at most one connection) per thread per database. + * </p> + * + * <h2>Transactions</h2> + * <p> + * There are two kinds of transaction: implicit transactions and explicit + * transactions. + * </p><p> + * An implicit transaction is created whenever a database operation is requested + * and there is no explicit transaction currently in progress. An implicit transaction + * only lasts for the duration of the database operation in question and then it + * is ended. If the database operation was successful, then its changes are committed. + * </p><p> + * An explicit transaction is started by calling {@link #beginTransaction} and + * specifying the desired transaction mode. Once an explicit transaction has begun, + * all subsequent database operations will be performed as part of that transaction. + * To end an explicit transaction, first call {@link #setTransactionSuccessful} if the + * transaction was successful, then call {@link #end}. If the transaction was + * marked successful, its changes will be committed, otherwise they will be rolled back. + * </p><p> + * Explicit transactions can also be nested. A nested explicit transaction is + * started with {@link #beginTransaction}, marked successful with + * {@link #setTransactionSuccessful}and ended with {@link #endTransaction}. + * If any nested transaction is not marked successful, then the entire transaction + * including all of its nested transactions will be rolled back + * when the outermost transaction is ended. + * </p><p> + * To improve concurrency, an explicit transaction can be yielded by calling + * {@link #yieldTransaction}. If there is contention for use of the database, + * then yielding ends the current transaction, commits its changes, releases the + * database connection for use by another session for a little while, and starts a + * new transaction with the same properties as the original one. + * Changes committed by {@link #yieldTransaction} cannot be rolled back. + * </p><p> + * When a transaction is started, the client can provide a {@link SQLiteTransactionListener} + * to listen for notifications of transaction-related events. + * </p><p> + * Recommended usage: + * <code><pre> + * // First, begin the transaction. + * session.beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED, 0); + * try { + * // Then do stuff... + * session.execute("INSERT INTO ...", null, 0); + * + * // As the very last step before ending the transaction, mark it successful. + * session.setTransactionSuccessful(); + * } finally { + * // Finally, end the transaction. + * // This statement will commit the transaction if it was marked successful or + * // roll it back otherwise. + * session.endTransaction(); + * } + * </pre></code> + * </p> + * + * <h2>Database connections</h2> + * <p> + * A {@link SQLiteDatabase} can have multiple active sessions at the same + * time. Each session acquires and releases connections to the database + * as needed to perform each requested database transaction. If all connections + * are in use, then database transactions on some sessions will block until a + * connection becomes available. + * </p><p> + * The session acquires a single database connection only for the duration + * of a single (implicit or explicit) database transaction, then releases it. + * This characteristic allows a small pool of database connections to be shared + * efficiently by multiple sessions as long as they are not all trying to perform + * database transactions at the same time. + * </p> + * + * <h2>Responsiveness</h2> + * <p> + * Because there are a limited number of database connections and the session holds + * a database connection for the entire duration of a database transaction, + * it is important to keep transactions short. This is especially important + * for read-write transactions since they may block other transactions + * from executing. Consider calling {@link #yieldTransaction} periodically + * during long-running transactions. + * </p><p> + * Another important consideration is that transactions that take too long to + * run may cause the application UI to become unresponsive. Even if the transaction + * is executed in a background thread, the user will get bored and + * frustrated if the application shows no data for several seconds while + * a transaction runs. + * </p><p> + * Guidelines: + * <ul> + * <li>Do not perform database transactions on the UI thread.</li> + * <li>Keep database transactions as short as possible.</li> + * <li>Simple queries often run faster than complex queries.</li> + * <li>Measure the performance of your database transactions.</li> + * <li>Consider what will happen when the size of the data set grows. + * A query that works well on 100 rows may struggle with 10,000.</li> + * </ul> + * + * <h2>Reentrance</h2> + * <p> + * This class must tolerate reentrant execution of SQLite operations because + * triggers may call custom SQLite functions that perform additional queries. + * </p> + * + * @hide + */ +public final class SQLiteSession { + private final SQLiteConnectionPool mConnectionPool; + + private SQLiteConnection mConnection; + private int mConnectionFlags; + private int mConnectionUseCount; + private Transaction mTransactionPool; + private Transaction mTransactionStack; + + /** + * Transaction mode: Deferred. + * <p> + * In a deferred transaction, no locks are acquired on the database + * until the first operation is performed. If the first operation is + * read-only, then a <code>SHARED</code> lock is acquired, otherwise + * a <code>RESERVED</code> lock is acquired. + * </p><p> + * While holding a <code>SHARED</code> lock, this session is only allowed to + * read but other sessions are allowed to read or write. + * While holding a <code>RESERVED</code> lock, this session is allowed to read + * or write but other sessions are only allowed to read. + * </p><p> + * Because the lock is only acquired when needed in a deferred transaction, + * it is possible for another session to write to the database first before + * this session has a chance to do anything. + * </p><p> + * Corresponds to the SQLite <code>BEGIN DEFERRED</code> transaction mode. + * </p> + */ + public static final int TRANSACTION_MODE_DEFERRED = 0; + + /** + * Transaction mode: Immediate. + * <p> + * When an immediate transaction begins, the session acquires a + * <code>RESERVED</code> lock. + * </p><p> + * While holding a <code>RESERVED</code> lock, this session is allowed to read + * or write but other sessions are only allowed to read. + * </p><p> + * Corresponds to the SQLite <code>BEGIN IMMEDIATE</code> transaction mode. + * </p> + */ + public static final int TRANSACTION_MODE_IMMEDIATE = 1; + + /** + * Transaction mode: Exclusive. + * <p> + * When an exclusive transaction begins, the session acquires an + * <code>EXCLUSIVE</code> lock. + * </p><p> + * While holding an <code>EXCLUSIVE</code> lock, this session is allowed to read + * or write but no other sessions are allowed to access the database. + * </p><p> + * Corresponds to the SQLite <code>BEGIN EXCLUSIVE</code> transaction mode. + * </p> + */ + public static final int TRANSACTION_MODE_EXCLUSIVE = 2; + + /** + * Creates a session bound to the specified connection pool. + * + * @param connectionPool The connection pool. + */ + public SQLiteSession(SQLiteConnectionPool connectionPool) { + if (connectionPool == null) { + throw new IllegalArgumentException("connectionPool must not be null"); + } + + mConnectionPool = connectionPool; + } + + /** + * Returns true if the session has a transaction in progress. + * + * @return True if the session has a transaction in progress. + */ + public boolean hasTransaction() { + return mTransactionStack != null; + } + + /** + * Returns true if the session has a nested transaction in progress. + * + * @return True if the session has a nested transaction in progress. + */ + public boolean hasNestedTransaction() { + return mTransactionStack != null && mTransactionStack.mParent != null; + } + + /** + * Returns true if the session has an active database connection. + * + * @return True if the session has an active database connection. + */ + public boolean hasConnection() { + return mConnection != null; + } + + /** + * Begins a transaction. + * <p> + * Transactions may nest. If the transaction is not in progress, + * then a database connection is obtained and a new transaction is started. + * Otherwise, a nested transaction is started. + * </p><p> + * Each call to {@link #beginTransaction} must be matched exactly by a call + * to {@link #endTransaction}. To mark a transaction as successful, + * call {@link #setTransactionSuccessful} before calling {@link #endTransaction}. + * If the transaction is not successful, or if any of its nested + * transactions were not successful, then the entire transaction will + * be rolled back when the outermost transaction is ended. + * </p> + * + * @param transactionMode The transaction mode. One of: {@link #TRANSACTION_MODE_DEFERRED}, + * {@link #TRANSACTION_MODE_IMMEDIATE}, or {@link #TRANSACTION_MODE_EXCLUSIVE}. + * Ignored when creating a nested transaction. + * @param transactionListener The transaction listener, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * + * @throws IllegalStateException if {@link #setTransactionSuccessful} has already been + * called for the current transaction. + * @throws SQLiteException if an error occurs. + * @throws OperationCanceledException if the operation was canceled. + * + * @see #setTransactionSuccessful + * @see #yieldTransaction + * @see #endTransaction + */ + public void beginTransaction(int transactionMode, + SQLiteTransactionListener transactionListener, int connectionFlags, + CancellationSignal cancellationSignal) { + throwIfTransactionMarkedSuccessful(); + beginTransactionUnchecked(transactionMode, transactionListener, connectionFlags, + cancellationSignal); + } + + private void beginTransactionUnchecked(int transactionMode, + SQLiteTransactionListener transactionListener, int connectionFlags, + CancellationSignal cancellationSignal) { + if (cancellationSignal != null) { + cancellationSignal.throwIfCanceled(); + } + + if (mTransactionStack == null) { + acquireConnection(null, connectionFlags, cancellationSignal); // might throw + } + try { + // Set up the transaction such that we can back out safely + // in case we fail part way. + if (mTransactionStack == null) { + // Execute SQL might throw a runtime exception. + switch (transactionMode) { + case TRANSACTION_MODE_IMMEDIATE: + mConnection.execute("BEGIN IMMEDIATE;", null, + cancellationSignal); // might throw + break; + case TRANSACTION_MODE_EXCLUSIVE: + mConnection.execute("BEGIN EXCLUSIVE;", null, + cancellationSignal); // might throw + break; + default: + mConnection.execute("BEGIN;", null, cancellationSignal); // might throw + break; + } + } + + // Listener might throw a runtime exception. + if (transactionListener != null) { + try { + transactionListener.onBegin(); // might throw + } catch (RuntimeException ex) { + if (mTransactionStack == null) { + mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw + } + throw ex; + } + } + + // Bookkeeping can't throw, except an OOM, which is just too bad... + Transaction transaction = obtainTransaction(transactionMode, transactionListener); + transaction.mParent = mTransactionStack; + mTransactionStack = transaction; + } finally { + if (mTransactionStack == null) { + releaseConnection(); // might throw + } + } + } + + /** + * Marks the current transaction as having completed successfully. + * <p> + * This method can be called at most once between {@link #beginTransaction} and + * {@link #endTransaction} to indicate that the changes made by the transaction should be + * committed. If this method is not called, the changes will be rolled back + * when the transaction is ended. + * </p> + * + * @throws IllegalStateException if there is no current transaction, or if + * {@link #setTransactionSuccessful} has already been called for the current transaction. + * + * @see #beginTransaction + * @see #endTransaction + */ + public void setTransactionSuccessful() { + throwIfNoTransaction(); + throwIfTransactionMarkedSuccessful(); + + mTransactionStack.mMarkedSuccessful = true; + } + + /** + * Ends the current transaction and commits or rolls back changes. + * <p> + * If this is the outermost transaction (not nested within any other + * transaction), then the changes are committed if {@link #setTransactionSuccessful} + * was called or rolled back otherwise. + * </p><p> + * This method must be called exactly once for each call to {@link #beginTransaction}. + * </p> + * + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * + * @throws IllegalStateException if there is no current transaction. + * @throws SQLiteException if an error occurs. + * @throws OperationCanceledException if the operation was canceled. + * + * @see #beginTransaction + * @see #setTransactionSuccessful + * @see #yieldTransaction + */ + public void endTransaction(CancellationSignal cancellationSignal) { + throwIfNoTransaction(); + assert mConnection != null; + + endTransactionUnchecked(cancellationSignal, false); + } + + private void endTransactionUnchecked(CancellationSignal cancellationSignal, boolean yielding) { + if (cancellationSignal != null) { + cancellationSignal.throwIfCanceled(); + } + + final Transaction top = mTransactionStack; + boolean successful = (top.mMarkedSuccessful || yielding) && !top.mChildFailed; + + RuntimeException listenerException = null; + final SQLiteTransactionListener listener = top.mListener; + if (listener != null) { + try { + if (successful) { + listener.onCommit(); // might throw + } else { + listener.onRollback(); // might throw + } + } catch (RuntimeException ex) { + listenerException = ex; + successful = false; + } + } + + mTransactionStack = top.mParent; + recycleTransaction(top); + + if (mTransactionStack != null) { + if (!successful) { + mTransactionStack.mChildFailed = true; + } + } else { + try { + if (successful) { + mConnection.execute("COMMIT;", null, cancellationSignal); // might throw + } else { + mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw + } + } finally { + releaseConnection(); // might throw + } + } + + if (listenerException != null) { + throw listenerException; + } + } + + /** + * Temporarily ends a transaction to let other threads have use of + * the database. Begins a new transaction after a specified delay. + * <p> + * If there are other threads waiting to acquire connections, + * then the current transaction is committed and the database + * connection is released. After a short delay, a new transaction + * is started. + * </p><p> + * The transaction is assumed to be successful so far. Do not call + * {@link #setTransactionSuccessful()} before calling this method. + * This method will fail if the transaction has already been marked + * successful. + * </p><p> + * The changes that were committed by a yield cannot be rolled back later. + * </p><p> + * Before this method was called, there must already have been + * a transaction in progress. When this method returns, there will + * still be a transaction in progress, either the same one as before + * or a new one if the transaction was actually yielded. + * </p><p> + * This method should not be called when there is a nested transaction + * in progress because it is not possible to yield a nested transaction. + * If <code>throwIfNested</code> is true, then attempting to yield + * a nested transaction will throw {@link IllegalStateException}, otherwise + * the method will return <code>false</code> in that case. + * </p><p> + * If there is no nested transaction in progress but a previous nested + * transaction failed, then the transaction is not yielded (because it + * must be rolled back) and this method returns <code>false</code>. + * </p> + * + * @param sleepAfterYieldDelayMillis A delay time to wait after yielding + * the database connection to allow other threads some time to run. + * If the value is less than or equal to zero, there will be no additional + * delay beyond the time it will take to begin a new transaction. + * @param throwIfUnsafe If true, then instead of returning false when no + * transaction is in progress, a nested transaction is in progress, or when + * the transaction has already been marked successful, throws {@link IllegalStateException}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return True if the transaction was actually yielded. + * + * @throws IllegalStateException if <code>throwIfNested</code> is true and + * there is no current transaction, there is a nested transaction in progress or + * if {@link #setTransactionSuccessful} has already been called for the current transaction. + * @throws SQLiteException if an error occurs. + * @throws OperationCanceledException if the operation was canceled. + * + * @see #beginTransaction + * @see #endTransaction + */ + public boolean yieldTransaction(long sleepAfterYieldDelayMillis, boolean throwIfUnsafe, + CancellationSignal cancellationSignal) { + if (throwIfUnsafe) { + throwIfNoTransaction(); + throwIfTransactionMarkedSuccessful(); + throwIfNestedTransaction(); + } else { + if (mTransactionStack == null || mTransactionStack.mMarkedSuccessful + || mTransactionStack.mParent != null) { + return false; + } + } + assert mConnection != null; + + if (mTransactionStack.mChildFailed) { + return false; + } + + return yieldTransactionUnchecked(sleepAfterYieldDelayMillis, + cancellationSignal); // might throw + } + + private boolean yieldTransactionUnchecked(long sleepAfterYieldDelayMillis, + CancellationSignal cancellationSignal) { + if (cancellationSignal != null) { + cancellationSignal.throwIfCanceled(); + } + + if (!mConnectionPool.shouldYieldConnection(mConnection, mConnectionFlags)) { + return false; + } + + final int transactionMode = mTransactionStack.mMode; + final SQLiteTransactionListener listener = mTransactionStack.mListener; + final int connectionFlags = mConnectionFlags; + endTransactionUnchecked(cancellationSignal, true); // might throw + + if (sleepAfterYieldDelayMillis > 0) { + try { + Thread.sleep(sleepAfterYieldDelayMillis); + } catch (InterruptedException ex) { + // we have been interrupted, that's all we need to do + } + } + + beginTransactionUnchecked(transactionMode, listener, connectionFlags, + cancellationSignal); // might throw + return true; + } + + /** + * Prepares a statement for execution but does not bind its parameters or execute it. + * <p> + * This method can be used to check for syntax errors during compilation + * prior to execution of the statement. If the {@code outStatementInfo} argument + * is not null, the provided {@link SQLiteStatementInfo} object is populated + * with information about the statement. + * </p><p> + * A prepared statement makes no reference to the arguments that may eventually + * be bound to it, consequently it it possible to cache certain prepared statements + * such as SELECT or INSERT/UPDATE statements. If the statement is cacheable, + * then it will be stored in the cache for later and reused if possible. + * </p> + * + * @param sql The SQL statement to prepare. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @param outStatementInfo The {@link SQLiteStatementInfo} object to populate + * with information about the statement, or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error. + * @throws OperationCanceledException if the operation was canceled. + */ + public void prepare(String sql, int connectionFlags, CancellationSignal cancellationSignal, + SQLiteStatementInfo outStatementInfo) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + if (cancellationSignal != null) { + cancellationSignal.throwIfCanceled(); + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + mConnection.prepare(sql, outStatementInfo); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Executes a statement that does not return a result. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public void execute(String sql, Object[] bindArgs, int connectionFlags, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { + return; + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + mConnection.execute(sql, bindArgs, cancellationSignal); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Executes a statement that returns a single <code>long</code> result. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The value of the first column in the first row of the result set + * as a <code>long</code>, or zero if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public long executeForLong(String sql, Object[] bindArgs, int connectionFlags, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { + return 0; + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + return mConnection.executeForLong(sql, bindArgs, cancellationSignal); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Executes a statement that returns a single {@link String} result. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The value of the first column in the first row of the result set + * as a <code>String</code>, or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public String executeForString(String sql, Object[] bindArgs, int connectionFlags, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { + return null; + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + return mConnection.executeForString(sql, bindArgs, cancellationSignal); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Executes a statement that returns a single BLOB result as a + * file descriptor to a shared memory region. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The file descriptor for a shared memory region that contains + * the value of the first column in the first row of the result set as a BLOB, + * or null if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs, + int connectionFlags, CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { + return null; + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + return mConnection.executeForBlobFileDescriptor(sql, bindArgs, + cancellationSignal); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Executes a statement that returns a count of the number of rows + * that were changed. Use for UPDATE or DELETE SQL statements. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The number of rows that were changed. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public int executeForChangedRowCount(String sql, Object[] bindArgs, int connectionFlags, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { + return 0; + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + return mConnection.executeForChangedRowCount(sql, bindArgs, + cancellationSignal); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Executes a statement that returns the row id of the last row inserted + * by the statement. Use for INSERT SQL statements. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The row id of the last row that was inserted, or 0 if none. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public long executeForLastInsertedRowId(String sql, Object[] bindArgs, int connectionFlags, + CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + + if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { + return 0; + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + return mConnection.executeForLastInsertedRowId(sql, bindArgs, + cancellationSignal); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Executes a statement and populates the specified {@link CursorWindow} + * with a range of results. Returns the number of rows that were counted + * during query execution. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param window The cursor window to clear and fill. + * @param startPos The start position for filling the window. + * @param requiredPos The position of a row that MUST be in the window. + * If it won't fit, then the query should discard part of what it filled + * so that it does. Must be greater than or equal to <code>startPos</code>. + * @param countAllRows True to count all rows that the query would return + * regagless of whether they fit in the window. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return The number of rows that were counted during query execution. Might + * not be all rows in the result set unless <code>countAllRows</code> is true. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + public int executeForCursorWindow(String sql, Object[] bindArgs, + CursorWindow window, int startPos, int requiredPos, boolean countAllRows, + int connectionFlags, CancellationSignal cancellationSignal) { + if (sql == null) { + throw new IllegalArgumentException("sql must not be null."); + } + if (window == null) { + throw new IllegalArgumentException("window must not be null."); + } + + if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) { + window.clear(); + return 0; + } + + acquireConnection(sql, connectionFlags, cancellationSignal); // might throw + try { + return mConnection.executeForCursorWindow(sql, bindArgs, + window, startPos, requiredPos, countAllRows, + cancellationSignal); // might throw + } finally { + releaseConnection(); // might throw + } + } + + /** + * Performs special reinterpretation of certain SQL statements such as "BEGIN", + * "COMMIT" and "ROLLBACK" to ensure that transaction state invariants are + * maintained. + * + * This function is mainly used to support legacy apps that perform their + * own transactions by executing raw SQL rather than calling {@link #beginTransaction} + * and the like. + * + * @param sql The SQL statement to execute. + * @param bindArgs The arguments to bind, or null if none. + * @param connectionFlags The connection flags to use if a connection must be + * acquired by this operation. Refer to {@link SQLiteConnectionPool}. + * @param cancellationSignal A signal to cancel the operation in progress, or null if none. + * @return True if the statement was of a special form that was handled here, + * false otherwise. + * + * @throws SQLiteException if an error occurs, such as a syntax error + * or invalid number of bind arguments. + * @throws OperationCanceledException if the operation was canceled. + */ + private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags, + CancellationSignal cancellationSignal) { + if (cancellationSignal != null) { + cancellationSignal.throwIfCanceled(); + } + + final int type = DatabaseUtils.getSqlStatementType(sql); + switch (type) { + case DatabaseUtils.STATEMENT_BEGIN: + beginTransaction(TRANSACTION_MODE_EXCLUSIVE, null, connectionFlags, + cancellationSignal); + return true; + + case DatabaseUtils.STATEMENT_COMMIT: + setTransactionSuccessful(); + endTransaction(cancellationSignal); + return true; + + case DatabaseUtils.STATEMENT_ABORT: + endTransaction(cancellationSignal); + return true; + } + return false; + } + + private void acquireConnection(String sql, int connectionFlags, + CancellationSignal cancellationSignal) { + if (mConnection == null) { + assert mConnectionUseCount == 0; + mConnection = mConnectionPool.acquireConnection(sql, connectionFlags, + cancellationSignal); // might throw + mConnectionFlags = connectionFlags; + } + mConnectionUseCount += 1; + } + + private void releaseConnection() { + assert mConnection != null; + assert mConnectionUseCount > 0; + if (--mConnectionUseCount == 0) { + try { + mConnectionPool.releaseConnection(mConnection); // might throw + } finally { + mConnection = null; + } + } + } + + private void throwIfNoTransaction() { + if (mTransactionStack == null) { + throw new IllegalStateException("Cannot perform this operation because " + + "there is no current transaction."); + } + } + + private void throwIfTransactionMarkedSuccessful() { + if (mTransactionStack != null && mTransactionStack.mMarkedSuccessful) { + throw new IllegalStateException("Cannot perform this operation because " + + "the transaction has already been marked successful. The only " + + "thing you can do now is call endTransaction()."); + } + } + + private void throwIfNestedTransaction() { + if (hasNestedTransaction()) { + throw new IllegalStateException("Cannot perform this operation because " + + "a nested transaction is in progress."); + } + } + + private Transaction obtainTransaction(int mode, SQLiteTransactionListener listener) { + Transaction transaction = mTransactionPool; + if (transaction != null) { + mTransactionPool = transaction.mParent; + transaction.mParent = null; + transaction.mMarkedSuccessful = false; + transaction.mChildFailed = false; + } else { + transaction = new Transaction(); + } + transaction.mMode = mode; + transaction.mListener = listener; + return transaction; + } + + private void recycleTransaction(Transaction transaction) { + transaction.mParent = mTransactionPool; + transaction.mListener = null; + mTransactionPool = transaction; + } + + private static final class Transaction { + public Transaction mParent; + public int mMode; + public SQLiteTransactionListener mListener; + public boolean mMarkedSuccessful; + public boolean mChildFailed; + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteStatement.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteStatement.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +import android.os.ParcelFileDescriptor; + +/** + * Represents a statement that can be executed against a database. The statement + * cannot return multiple rows or columns, but single value (1 x 1) result sets + * are supported. + * <p> + * This class is not thread-safe. + * </p> + */ +public final class SQLiteStatement extends SQLiteProgram { + SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) { + super(db, sql, bindArgs, null); + } + + /** + * Execute this SQL statement, if it is not a SELECT / INSERT / DELETE / UPDATE, for example + * CREATE / DROP table, view, trigger, index etc. + * + * @throws android.database.SQLException If the SQL string is invalid for + * some reason + */ + public void execute() { + acquireReference(); + try { + getSession().execute(getSql(), getBindArgs(), getConnectionFlags(), null); + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + throw ex; + } finally { + releaseReference(); + } + } + + /** + * Execute this SQL statement, if the the number of rows affected by execution of this SQL + * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements. + * + * @return the number of rows affected by this SQL statement execution. + * @throws android.database.SQLException If the SQL string is invalid for + * some reason + */ + public int executeUpdateDelete() { + acquireReference(); + try { + return getSession().executeForChangedRowCount( + getSql(), getBindArgs(), getConnectionFlags(), null); + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + throw ex; + } finally { + releaseReference(); + } + } + + /** + * Execute this SQL statement and return the ID of the row inserted due to this call. + * The SQL statement should be an INSERT for this to be a useful call. + * + * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise. + * + * @throws android.database.SQLException If the SQL string is invalid for + * some reason + */ + public long executeInsert() { + acquireReference(); + try { + return getSession().executeForLastInsertedRowId( + getSql(), getBindArgs(), getConnectionFlags(), null); + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + throw ex; + } finally { + releaseReference(); + } + } + + /** + * Execute a statement that returns a 1 by 1 table with a numeric value. + * For example, SELECT COUNT(*) FROM table; + * + * @return The result of the query. + * + * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows + */ + public long simpleQueryForLong() { + acquireReference(); + try { + return getSession().executeForLong( + getSql(), getBindArgs(), getConnectionFlags(), null); + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + throw ex; + } finally { + releaseReference(); + } + } + + /** + * Execute a statement that returns a 1 by 1 table with a text value. + * For example, SELECT COUNT(*) FROM table; + * + * @return The result of the query. + * + * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows + */ + public String simpleQueryForString() { + acquireReference(); + try { + return getSession().executeForString( + getSql(), getBindArgs(), getConnectionFlags(), null); + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + throw ex; + } finally { + releaseReference(); + } + } + + /** + * Executes a statement that returns a 1 by 1 table with a blob value. + * + * @return A read-only file descriptor for a copy of the blob value, or {@code null} + * if the value is null or could not be read for some reason. + * + * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows + */ + public ParcelFileDescriptor simpleQueryForBlobFileDescriptor() { + acquireReference(); + try { + return getSession().executeForBlobFileDescriptor( + getSql(), getBindArgs(), getConnectionFlags(), null); + } catch (SQLiteDatabaseCorruptException ex) { + onCorruption(); + throw ex; + } finally { + releaseReference(); + } + } + + @Override + public String toString() { + return "SQLiteProgram: " + getSql(); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteStatementInfo.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteStatementInfo.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * Describes a SQLite statement. + * + * @hide + */ +public final class SQLiteStatementInfo { + /** + * The number of parameters that the statement has. + */ + public int numParameters; + + /** + * The names of all columns in the result set of the statement. + */ + public String[] columnNames; + + /** + * True if the statement is read-only. + */ + public boolean readOnly; +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteTableLockedException.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteTableLockedException.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +public class SQLiteTableLockedException extends SQLiteException { + public SQLiteTableLockedException() {} + + public SQLiteTableLockedException(String error) { + super(error); + } +} diff --git a/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteTransactionListener.java b/android_studio/app/src/main/java/org/sqlite/database/sqlite/SQLiteTransactionListener.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +package org.sqlite.database.sqlite; + +/** + * A listener for transaction events. + */ +public interface SQLiteTransactionListener { + /** + * Called immediately after the transaction begins. + */ + void onBegin(); + + /** + * Called immediately before commiting the transaction. + */ + void onCommit(); + + /** + * Called if the transaction is about to be rolled back. + */ + void onRollback(); +} diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_arm_service.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_arm_service.h @@ -0,0 +1,439 @@ +/* + This file is part of GNUnet + Copyright (C) 2009, 2016 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 + * API to access gnunet-arm + * + * @defgroup arm ARM service + * Automatic Restart Manager + * + * @see [Documentation](https://gnunet.org/arm) + * + * @{ + */ + +#ifndef GNUNET_ARM_SERVICE_H +#define GNUNET_ARM_SERVICE_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_util_lib.h" + +/** + * Version of the arm API. + */ +#define GNUNET_ARM_VERSION 0x00000003 + + +/** + * Statuses of the requests that client can send to ARM. + */ +enum GNUNET_ARM_RequestStatus +{ + /** + * Message was sent successfully. + */ + GNUNET_ARM_REQUEST_SENT_OK = 0, + + /** + * We disconnected from ARM, and request was not sent. + */ + GNUNET_ARM_REQUEST_DISCONNECTED = 2 +}; + + +/** + * Statuses of services. + */ +enum GNUNET_ARM_ServiceMonitorStatus +{ + /** + * Dummy message. + */ + GNUNET_ARM_SERVICE_MONITORING_STARTED = 0, + + /** + * Service was stopped. + */ + GNUNET_ARM_SERVICE_STOPPED = 1, + + /** + * Service starting was initiated + */ + GNUNET_ARM_SERVICE_STARTING = 2, + + /** + * Service stopping was initiated + */ + GNUNET_ARM_SERVICE_STOPPING = 3 +}; + + +/** + * Replies to ARM requests + */ +enum GNUNET_ARM_Result +{ + /** + * Service was stopped (never sent for ARM itself). + */ + GNUNET_ARM_RESULT_STOPPED = 0, + + /** + * ARM stopping was initiated (there's no "stopped" for ARM itself). + */ + GNUNET_ARM_RESULT_STOPPING = 1, + + /** + * Service starting was initiated + */ + GNUNET_ARM_RESULT_STARTING = 2, + + /** + * Asked to start it, but it's already starting. + */ + GNUNET_ARM_RESULT_IS_STARTING_ALREADY = 3, + + /** + * Asked to stop it, but it's already stopping. + */ + GNUNET_ARM_RESULT_IS_STOPPING_ALREADY = 4, + + /** + * Asked to start it, but it's already started. + */ + GNUNET_ARM_RESULT_IS_STARTED_ALREADY = 5, + + /** + * Asked to stop it, but it's already stopped. + */ + GNUNET_ARM_RESULT_IS_STOPPED_ALREADY = 6, + + /** + * Asked to start or stop a service, but it's not known. + */ + GNUNET_ARM_RESULT_IS_NOT_KNOWN = 7, + + /** + * Tried to start a service, but that failed for some reason. + */ + GNUNET_ARM_RESULT_START_FAILED = 8, + + /** + * Asked to start something, but ARM is shutting down and can't comply. + */ + GNUNET_ARM_RESULT_IN_SHUTDOWN = 9 +}; + + +/** + * Status of a service managed by ARM. + */ +enum GNUNET_ARM_ServiceStatus +{ + /** + * Service is stopped. + */ + GNUNET_ARM_SERVICE_STATUS_STOPPED = 0, + + /** + * Service has been started and is currently running. + */ + GNUNET_ARM_SERVICE_STATUS_STARTED = 1, + + /** + * The service has previously failed, and + * will be restarted. + */ + GNUNET_ARM_SERVICE_STATUS_FAILED = 2, + + /** + * The service was started, but then exited normally. + */ + GNUNET_ARM_SERVICE_STATUS_FINISHED = 3, + + /** + * The service was started, and we're currently waiting + * for it to be stopped. + */ + GNUNET_ARM_SERVICE_STATUS_STOPPING = 4, +}; + + +/** + * Information about a service managed by ARM. + */ +struct GNUNET_ARM_ServiceInfo +{ + /** + * The current status of the service. + */ + enum GNUNET_ARM_ServiceStatus status; + + /** + * The name of the service. + */ + const char *name; + + /** + * The binary used to execute the service. + */ + const char *binary; + + /** + * Time when the service will be restarted, if applicable + * to the current status. + */ + struct GNUNET_TIME_Absolute restart_at; + + /** + * Time when the service was first started, if applicable. + */ + struct GNUNET_TIME_Absolute last_started_at; + + /** + * Last process exit status. + */ + int last_exit_status; +}; + + +/** + * Handle for interacting with ARM. + */ +struct GNUNET_ARM_Handle; + +/** + * Handle for an ARM operation. + */ +struct GNUNET_ARM_Operation; + + +/** + * Function called whenever we connect to or disconnect from ARM. + * + * @param cls closure + * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected, + * #GNUNET_SYSERR if there was an error. + */ +typedef void +(*GNUNET_ARM_ConnectionStatusCallback) ( + void *cls, + enum GNUNET_GenericReturnValue connected); + + +/** + * Function called in response to a start/stop request. + * Will be called when request was not sent successfully, + * or when a reply comes. If the request was not sent successfully, + * @a rs will indicate that, and @a result will be undefined. + * + * @param cls closure + * @param rs status of the request + * @param result result of the operation + */ +typedef void +(*GNUNET_ARM_ResultCallback) ( + void *cls, + enum GNUNET_ARM_RequestStatus rs, + enum GNUNET_ARM_Result result); + + +/** + * Callback function invoked when list operation is complete. + * Will be called when request was not sent successfully, + * or when a reply comes. If the request was not sent successfully, + * @a rs will indicate that, and @a count and @a list will be undefined. + * + * @param cls closure + * @param rs status of the request + * @param count number of strings in the list + * @param list list of services managed by arm + */ +typedef void +(*GNUNET_ARM_ServiceListCallback) ( + void *cls, + enum GNUNET_ARM_RequestStatus rs, + unsigned int count, + const struct GNUNET_ARM_ServiceInfo *list); + + +/** + * Set up a context for communicating with ARM, then + * start connecting to the ARM service using that context. + * + * @param cfg configuration to use (needed to contact ARM; + * the ARM service may internally use a different + * configuration to determine how to start the service). + * @param conn_status will be called when connecting/disconnecting + * @param conn_status_cls closure for @a conn_status + * @return context to use for further ARM operations, NULL on error. + */ +struct GNUNET_ARM_Handle * +GNUNET_ARM_connect ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_ARM_ConnectionStatusCallback conn_status, + void *conn_status_cls); + + +/** + * Disconnect from the ARM service and destroy the handle. + * + * @param[in] h the handle that was being used + */ +void +GNUNET_ARM_disconnect ( + struct GNUNET_ARM_Handle *h); + + +/** + * Abort an operation. Only prevents the callback from being + * called, the operation may still complete. + * + * @param op operation to cancel + */ +void +GNUNET_ARM_operation_cancel ( + struct GNUNET_ARM_Operation *op); + + +/** + * Request a list of running services. + * + * @param h handle to ARM + * @param cont callback to invoke after request is sent or is not sent + * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error + */ +struct GNUNET_ARM_Operation * +GNUNET_ARM_request_service_list ( + struct GNUNET_ARM_Handle *h, + GNUNET_ARM_ServiceListCallback cont, + void *cont_cls); + + +/** + * Request a service to be stopped. + * Stopping arm itself will not invalidate its handle, and + * ARM API will try to restore connection to the ARM service, + * even if ARM connection was lost because you asked for ARM to be stopped. + * Call #GNUNET_ARM_disconnect() to free the handle and prevent + * further connection attempts. + * + * @param h handle to ARM + * @param service_name name of the service + * @param cont callback to invoke after request is sent or is not sent + * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error + */ +struct GNUNET_ARM_Operation * +GNUNET_ARM_request_service_stop ( + struct GNUNET_ARM_Handle *h, + const char *service_name, + GNUNET_ARM_ResultCallback cont, + void *cont_cls); + + +/** + * Request for a service to be started. + * + * @param h handle to ARM + * @param service_name name of the service + * @param std_inheritance inheritance of std streams + * @param cont callback to invoke after request is sent or not sent + * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error + */ +struct GNUNET_ARM_Operation * +GNUNET_ARM_request_service_start ( + struct GNUNET_ARM_Handle *h, + const char *service_name, + enum GNUNET_OS_InheritStdioFlags std_inheritance, + GNUNET_ARM_ResultCallback cont, + void *cont_cls); + + +/** + * Handle for monitoring ARM. + */ +struct GNUNET_ARM_MonitorHandle; + + +/** + * Function called in when a status update arrives. + * + * @param cls closure + * @param service service name + * @param status status of the service + */ +typedef void +(*GNUNET_ARM_ServiceMonitorCallback) ( + void *cls, + const char *service, + enum GNUNET_ARM_ServiceMonitorStatus status); + + +/** + * Setup a context for monitoring ARM, then + * start connecting to the ARM service for monitoring using that context. + * + * @param cfg configuration to use (needed to contact ARM; + * the ARM service may internally use a different + * configuration to determine how to start the service). + * @param cont callback to invoke on status updates + * @param cont_cls closure for @a cont + * @return context to use for further ARM monitor operations, NULL on error. + */ +struct GNUNET_ARM_MonitorHandle * +GNUNET_ARM_monitor_start ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_ARM_ServiceMonitorCallback cont, + void *cont_cls); + + +/** + * Disconnect from the ARM service and destroy the handle. + * + * @param h the handle that was being used + */ +void +GNUNET_ARM_monitor_stop ( + struct GNUNET_ARM_MonitorHandle *h); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ /* end of group */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_bandwidth_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_bandwidth_lib.h @@ -0,0 +1,364 @@ +/* + 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 + */ + +/** + * @addtogroup libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * + * @file + * Functions related to bandwidth (unit) + * + * @defgroup bandwidth Bandwidth library + * Functions related to bandwidth (unit) + * @{ + */ + +#if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_BANDWIDTH_LIB_H +#define GNUNET_BANDWIDTH_LIB_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_time_lib.h" + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * 32-bit bandwidth used for network exchange by GNUnet, in bytes per second. + */ +struct GNUNET_BANDWIDTH_Value32NBO +{ + /** + * The actual value (bytes per second). + */ + uint32_t value__ GNUNET_PACKED; +}; + +GNUNET_NETWORK_STRUCT_END + + +/** + * Callback to be called by the bandwidth tracker if the tracker + * was updated and the client should update it's delay values + * + * @param cls a closure to pass + */ +typedef void (*GNUNET_BANDWIDTH_TrackerUpdateCallback) (void *cls); + + +/** + * Callback to be called by the bandwidth tracker if the tracker + * was updated and the client should update it's delay values + * + * @param cls a closure to pass + */ +typedef void (*GNUNET_BANDWIDTH_ExcessNotificationCallback) (void *cls); + + +/** + * Struct to track available bandwidth. Combines a time stamp with a + * number of bytes transmitted, a quota and a maximum amount that + * carries over. Not opaque so that it can be inlined into data + * structures (reducing malloc-ing); however, values should not be + * accessed directly by clients (hence the '__'). + */ +struct GNUNET_BANDWIDTH_Tracker +{ + /** + * Closure for @e update_cb. + */ + void *update_cb_cls; + + /** + * Function we call if the tracker's bandwidth is increased and a + * previously returned timeout might now expire earlier. + */ + GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb; + + /** + * Closure for @e excess_cb. + */ + void *excess_cb_cls; + + /** + * Function we call if the tracker is about to throw + * away bandwidth due to excess (max carry exceeded). + */ + GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb; + + /** + * Number of bytes consumed since we last updated the tracker. + */ + int64_t consumption_since_last_update__; + + /** + * Task scheduled to call the @e excess_cb once we have + * reached the maximum bandwidth the tracker can hold. + */ + struct GNUNET_SCHEDULER_Task *excess_task; + + /** + * Time when we last updated the tracker. + */ + struct GNUNET_TIME_Absolute last_update__; + + /** + * Bandwidth limit to enforce in bytes per second. + */ + uint32_t available_bytes_per_s__; + + /** + * Maximum number of seconds over which bandwidth may "accumulate". + * Note that additionally, we also always allow at least + * #GNUNET_MAX_MESSAGE_SIZE to accumulate. + */ + uint32_t max_carry_s__; +}; + + +/** + * Convenience definition to use for 0-bandwidth. + */ +#define GNUNET_BANDWIDTH_ZERO GNUNET_BANDWIDTH_value_init (0) + + +/** + * Create a new bandwidth value. + * + * @param bytes_per_second value to create + * @return the new bandwidth value + */ +struct GNUNET_BANDWIDTH_Value32NBO +GNUNET_BANDWIDTH_value_init (uint32_t bytes_per_second); + + +/** + * Maximum possible bandwidth value. + */ +#define GNUNET_BANDWIDTH_VALUE_MAX GNUNET_BANDWIDTH_value_init (UINT32_MAX) + + +/** + * At the given bandwidth, calculate how much traffic will be + * available until the given deadline. + * + * @param bps bandwidth + * @param deadline when is the deadline + * @return number of bytes available at bps until deadline + */ +uint64_t +GNUNET_BANDWIDTH_value_get_available_until ( + struct GNUNET_BANDWIDTH_Value32NBO bps, + struct GNUNET_TIME_Relative deadline); + + +/** + * At the given bandwidth, calculate how long it would take for + * 'size' bytes to be transmitted. + * + * @param bps bandwidth + * @param size number of bytes we want to have available + * @return how long it would take + */ +struct GNUNET_TIME_Relative +GNUNET_BANDWIDTH_value_get_delay_for (struct GNUNET_BANDWIDTH_Value32NBO bps, + uint64_t size); + + +/** + * Compute the MIN of two bandwidth values. + * + * @param b1 first value + * @param b2 second value + * @return the min of b1 and b2 + */ +struct GNUNET_BANDWIDTH_Value32NBO +GNUNET_BANDWIDTH_value_min (struct GNUNET_BANDWIDTH_Value32NBO b1, + struct GNUNET_BANDWIDTH_Value32NBO b2); + + +/** + * Compute the MAX of two bandwidth values. + * + * @param b1 first value + * @param b2 second value + * @return the min of b1 and b2 + */ +struct GNUNET_BANDWIDTH_Value32NBO +GNUNET_BANDWIDTH_value_max (struct GNUNET_BANDWIDTH_Value32NBO b1, + struct GNUNET_BANDWIDTH_Value32NBO b2); + + +/** + * Compute the SUM of two bandwidth values. + * + * @param b1 first value + * @param b2 second value + * @return the sum of b1 and b2 + */ +struct GNUNET_BANDWIDTH_Value32NBO +GNUNET_BANDWIDTH_value_sum (struct GNUNET_BANDWIDTH_Value32NBO b1, + struct GNUNET_BANDWIDTH_Value32NBO b2); + + +/** + * Initialize bandwidth tracker. Note that in addition to the + * 'max_carry_s' limit, we also always allow at least + * #GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the + * bytes-per-second limit is so small that within 'max_carry_s' not + * even #GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is + * ignored and replaced by #GNUNET_MAX_MESSAGE_SIZE (which is in + * bytes). + * + * @param av tracker to initialize + * @param update_cb callback to notify a client about the tracker being updated + * @param update_cb_cls cls for the @a update_cb callback + * @param bytes_per_second_limit initial limit to assume + * @param max_carry_s maximum number of seconds unused bandwidth + * may accumulate before it expires + */ +void +GNUNET_BANDWIDTH_tracker_init ( + struct GNUNET_BANDWIDTH_Tracker *av, + GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, + void *update_cb_cls, + struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, + uint32_t max_carry_s); + + +/** + * Initialize bandwidth tracker. Note that in addition to the + * 'max_carry_s' limit, we also always allow at least + * #GNUNET_MAX_MESSAGE_SIZE to accumulate. So if the + * bytes-per-second limit is so small that within 'max_carry_s' not + * even #GNUNET_MAX_MESSAGE_SIZE is allowed to accumulate, it is + * ignored and replaced by #GNUNET_MAX_MESSAGE_SIZE (which is in + * bytes). + * + * @param av tracker to initialize + * @param update_cb callback to notify a client about the tracker being updated + * @param update_cb_cls cls for the @a update_cb callback + * @param bytes_per_second_limit initial limit to assume + * @param max_carry_s maximum number of seconds unused bandwidth + * may accumulate before it expires + * @param excess_cb callback to notify if we have excess bandwidth + * @param excess_cb_cls closure for @a excess_cb + */ +void +GNUNET_BANDWIDTH_tracker_init2 ( + struct GNUNET_BANDWIDTH_Tracker *av, + GNUNET_BANDWIDTH_TrackerUpdateCallback update_cb, + void *update_cb_cls, + struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit, + uint32_t max_carry_s, + GNUNET_BANDWIDTH_ExcessNotificationCallback excess_cb, + void *excess_cb_cls); + + +/** + * Stop notifying about tracker updates and excess notifications + * + * @param av the respective trackers + */ +void +GNUNET_BANDWIDTH_tracker_notification_stop ( + struct GNUNET_BANDWIDTH_Tracker *av); + + +/** + * Notify the tracker that a certain number of bytes of bandwidth have + * been consumed. Note that it is legal to consume bytes even if not + * enough bandwidth is available (in that case, + * #GNUNET_BANDWIDTH_tracker_get_delay() may return non-zero delay values + * even for a size of zero for a while). + * + * @param av tracker to update + * @param size number of bytes consumed + * @return #GNUNET_YES if this consumption is above the limit + */ +int +GNUNET_BANDWIDTH_tracker_consume (struct GNUNET_BANDWIDTH_Tracker *av, + ssize_t size); + + +/** + * Compute how long we should wait until consuming @a size + * bytes of bandwidth in order to stay within the given + * quota. + * + * @param av tracker to query + * @param size number of bytes we would like to consume + * @return time to wait for consumption to be OK + */ +struct GNUNET_TIME_Relative +GNUNET_BANDWIDTH_tracker_get_delay (struct GNUNET_BANDWIDTH_Tracker *av, + size_t size); + + +/** + * Compute how many bytes are available for consumption right now. + * quota. + * + * @param av tracker to query + * @return number of bytes available for consumption right now + */ +int64_t +GNUNET_BANDWIDTH_tracker_get_available (struct GNUNET_BANDWIDTH_Tracker *av); + + +/** + * Update quota of bandwidth tracker. + * + * @param av tracker to initialize + * @param bytes_per_second_limit new limit to assume + */ +void +GNUNET_BANDWIDTH_tracker_update_quota ( + struct GNUNET_BANDWIDTH_Tracker *av, + struct GNUNET_BANDWIDTH_Value32NBO bytes_per_second_limit); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_BANDWIDTH_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_bandwidth_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_bio_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_bio_lib.h @@ -0,0 +1,658 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009 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 + * Buffered IO library + * + * @defgroup bio BIO library + * Buffered binary disk IO (with endianness conversion) + * @{ + */ + +#include "gnunet_common.h" +#if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_BIO_LIB_H +#define GNUNET_BIO_LIB_H + + +#include "gnunet_container_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/****************************** READING API *******************************/ + +/** + * Handle for buffered reading. + */ +struct GNUNET_BIO_ReadHandle; + + +/** + * Open a file for reading. + * + * @param fn file name to be opened + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_ReadHandle * +GNUNET_BIO_read_open_file (const char *fn); + + +/** + * Create a handle from an existing allocated buffer. + * + * @param buffer the buffer to use as source + * @param size the total size in bytes of the buffer + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_ReadHandle * +GNUNET_BIO_read_open_buffer (void *buffer, size_t size); + + +/** + * Close an open handle. Reports if any errors reading + * from the file were encountered. + * + * @param h file handle + * @param emsg set to the error message + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, char **emsg); + +/** + * Set read error to handle + * + * @param h the handle + * @param emsg the message + */ +void +GNUNET_BIO_read_set_error (struct GNUNET_BIO_ReadHandle *h, const char* emsg); + + +/** + * Read some contents into a buffer. + * + * @param h the IO handle to read from + * @param what describes what is being read (for error message creation) + * @param result the buffer to write the result to + * @param len the number of bytes to read + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, + const char *what, + void *result, + size_t len); + + +/** + * Read 0-terminated string. + * + * @param h the IO handle to read from + * @param what describes what is being read (for error message creation) + * @param result where to store the pointer to the (allocated) string + * (note that *result could be set to NULL as well) + * @param max_length maximum allowed length for the string + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, + const char *what, + char **result, + size_t max_length); + + + +/** + * Read a float. + * + * @param h the IO handle to read from + * @param what describes what is being read (for error message creation) + * @param f address of float to read + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read_float (struct GNUNET_BIO_ReadHandle *h, + const char *what, + float *f); + + +/** + * Read a double. + * + * @param h the IO handle to read from + * @param what describes what is being read (for error message creation) + * @param f address of double to read + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read_double (struct GNUNET_BIO_ReadHandle *h, + const char *what, + double *f); + + +/** + * Read an (u)int32_t. + * + * @param h the IO handle to read from + * @param what describes what is being read (for error message creation) + * @param i where to store the data + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read_int32 (struct GNUNET_BIO_ReadHandle *h, + const char *what, + int32_t *i); + + +/** + * Read an (u)int64_t. + * + * @param h the IO handle to read from + * @param what describes what is being read (for error message creation) + * @param i where to store the data + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read_int64 (struct GNUNET_BIO_ReadHandle *h, + const char *what, + int64_t *i); + + +/****************************** WRITING API *******************************/ + +/** + * Handle for buffered writing. + */ +struct GNUNET_BIO_WriteHandle; + +/** + * Open a file for writing. + * + * @param fn name of the file to be opened + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_WriteHandle * +GNUNET_BIO_write_open_file (const char *fn); + + +/** + * Create a handle backed by an in-memory buffer. + * + * @return IO handle on success, NULL on error + */ +struct GNUNET_BIO_WriteHandle * +GNUNET_BIO_write_open_buffer (void); + + +/** + * Force a file-based buffered writer to flush its buffer. + * If the handle does not use a file, this function returns #GNUNET_OK + * without doing anything. + * + * @param h the IO handle + * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned + * and the file is closed + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h); + + +/** + * Get the IO handle's contents. + * If the handle doesn't use an in-memory buffer, this function returns + * #GNUNET_SYSERR. + * + * @param h the IO handle + * @param emsg set to the (allocated) error message + * if the handle has an error message the return value is #GNUNET_SYSERR + * @param contents where to store the pointer to the handle's contents + * @param size where to store the size of @e contents + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_get_buffer_contents (struct GNUNET_BIO_WriteHandle *h, + char **emsg, + void **contents, + size_t *size); + + +/** + * Close an IO handle. + * If the handle was using a file, the file will be closed. + * + * @param h file handle + * @param emsg set to the (allocated) error message + * if the handle has an error message, the return value is #GNUNET_SYSERR + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h, char **emsg); + + +/** + * Write a buffer to a handle. + * + * @param h the IO handle to write to + * @param what what is being written (for error message creation) + * @param buffer the data to write + * @param n number of bytes to write + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, + const char *what, + const void *buffer, + size_t n); + + +/** + * Write a 0-terminated string. + * + * @param h the IO handle to write to + * @param what what is being written (for error message creation) + * @param s string to write (can be NULL) + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, + const char *what, + const char *s); + + + +/** + * Write a float. + * + * @param h the IO handle to write to + * @param what what is being written (for error message creation) + * @param f float to write (must be a variable) + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write_float (struct GNUNET_BIO_WriteHandle *h, + const char *what, + float f); + +/** + * Write a double. + * + * @param h the IO handle to write to + * @param what what is being written (for error message creation) + * @param f double to write (must be a variable) + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write_double (struct GNUNET_BIO_WriteHandle *h, + const char *what, + double f); + + +/** + * Write an (u)int32_t. + * + * @param h the IO handle to write to + * @param what what is being written (for error message creation) + * @param i 32-bit integer to write + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h, + const char *what, + int32_t i); + + +/** + * Write an (u)int64_t. + * + * @param h the IO handle to write to + * @param what what is being written (for error message creation) + * @param i 64-bit integer to write + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h, + const char *what, + int64_t i); + + +/****************************** READ SPEC API ***************************/ + + +/** + * Function used to deserialize data read from @a h and store it into @a + * target. + * + * @param cls closure (can be NULL) + * @param h the IO handle to read from + * @param what what is being read (for error message creation) + * @param target where to store the data + * @param target_size how many bytes can be written in @a target + * can be 0 if the size is unknown or is not fixed + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +typedef int +(*GNUNET_BIO_ReadHandler)(void *cls, + struct GNUNET_BIO_ReadHandle *h, + const char *what, + void *target, + size_t target_size); + + +/** + * Structure specifying a reading operation on an IO handle. + */ +struct GNUNET_BIO_ReadSpec +{ + /** + * Function performing data deserialization. + */ + GNUNET_BIO_ReadHandler rh; + + /** + * Closure for @e rh. Can be NULL. + */ + void *cls; + + /** + * What is being read (for error message creation) + */ + const char *what; + + /** + * Destination buffer. Can also be a pointer to a pointer, especially for + * dynamically allocated structures. + */ + void *target; + + /** + * Size of @e target. Can be 0 if unknown or not fixed. + */ + size_t size; +}; + + +/** + * End of specifications marker. + */ +#define GNUNET_BIO_read_spec_end() \ + { NULL, NULL, NULL, NULL, 0 } + + +/** + * Create the specification to read a certain amount of bytes. + * + * @param what describes what is being read (for error message creation) + * @param result the buffer to write the result to + * @param len the number of bytes to read + * @return the read spec + */ +struct GNUNET_BIO_ReadSpec +GNUNET_BIO_read_spec_object (const char *what, + void *result, + size_t size); + + +/** + * Create the specification to read a 0-terminated string. + * + * @param what describes what is being read (for error message creation) + * @param result where to store the pointer to the (allocated) string + * (note that *result could be set to NULL as well) + * @param max_length maximum allowed length for the string + * @return the read spec + */ +struct GNUNET_BIO_ReadSpec +GNUNET_BIO_read_spec_string (const char *what, + char **result, + size_t max_length); + + + +/** + * Create the specification to read an (u)int32_t. + * + * @param what describes what is being read (for error message creation) + * @param i where to store the data + * @return the read spec + */ +struct GNUNET_BIO_ReadSpec +GNUNET_BIO_read_spec_int32 (const char *what, + int32_t *i); + + +/** + * Create the specification to read an (u)int64_t. + * + * @param what describes what is being read (for error message creation) + * @param i where to store the data + * @return the read spec + */ +struct GNUNET_BIO_ReadSpec +GNUNET_BIO_read_spec_int64 (const char *what, + int64_t *i); + + +/** + * Create the specification to read a float. + * + * @param what describes what is being read (for error message creation) + * @param f address of float to read + */ +struct GNUNET_BIO_ReadSpec +GNUNET_BIO_read_spec_float (const char *what, float *f); + + +/** + * Create the specification to read a double. + * + * @param what describes what is being read (for error message creation) + * @param f address of double to read + */ +struct GNUNET_BIO_ReadSpec +GNUNET_BIO_read_spec_double (const char *what, double *f); + + +/** + * Execute the read specifications in order. + * + * @param h the IO handle to read from + * @param rs array of read specs + * the last element must be #GNUNET_BIO_read_spec_end + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_read_spec_commit (struct GNUNET_BIO_ReadHandle *h, + struct GNUNET_BIO_ReadSpec *rs); + + +/******************************* WRITE SPEC API *****************************/ + + +/** + * Function used to serialize data from a buffer and write it to @a h. + * + * @param cls closure (can be NULL) + * @param h the IO handle to write to + * @param what what is being written (for error message creation) + * @param source the data to write + * @param source_size how many bytes should be written + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +typedef int +(*GNUNET_BIO_WriteHandler) (void *cls, + struct GNUNET_BIO_WriteHandle *h, + const char *what, + void *source, + size_t source_size); + + +/** + * Structure specifying a writing operation on an IO handle. + */ +struct GNUNET_BIO_WriteSpec +{ + /** + * Function performing data serialization. + */ + GNUNET_BIO_WriteHandler wh; + + /** + * Closure for @e rh. Can be NULL. + */ + void *cls; + + /** + * What is being read (for error message creation) + */ + const char *what; + + /** + * Source buffer. The data in this buffer will be written to the handle. + */ + void *source; + + /** + * Size of @e source. If it's smaller than the real size of @e source, only + * this many bytes will be written. + */ + size_t source_size; +}; + + +/** + * End of specifications marker. + */ +#define GNUNET_BIO_write_spec_end() \ + { NULL, NULL, NULL, NULL, 0 } + + +/** + * Create the specification to read some bytes. + * + * @param what describes what is being written (for error message creation) + * @param source the data to write + * @param size how many bytes should be written + * @return the write spec + */ +struct GNUNET_BIO_WriteSpec +GNUNET_BIO_write_spec_object (const char *what, + void *source, + size_t size); + + +/** + * Create the specification to write a 0-terminated string. + * + * @param what describes what is being read (for error message creation) + * @param s string to write (can be NULL) + * @return the read spec + */ +struct GNUNET_BIO_WriteSpec +GNUNET_BIO_write_spec_string (const char *what, + const char *s); + + +/** + * Create the specification to write an (u)int32_t. + * + * @param what describes what is being written (for error message creation) + * @param i pointer to a 32-bit integer + * @return the write spec + */ +struct GNUNET_BIO_WriteSpec +GNUNET_BIO_write_spec_int32 (const char *what, + int32_t *i); + + +/** + * Create the specification to write an (u)int64_t. + * + * @param what describes what is being written (for error message creation) + * @param i pointer to a 64-bit integer + * @return the write spec + */ +struct GNUNET_BIO_WriteSpec +GNUNET_BIO_write_spec_int64 (const char *what, + int64_t *i); + + +/** + * Create the specification to write a float. + * + * @param what describes what is being written (for error message creation) + * @param f pointer to a float + * @return the write spec + */ +struct GNUNET_BIO_WriteSpec +GNUNET_BIO_write_spec_float (const char *what, float *f); + + +/** + * Create the specification to write an double. + * + * @param what describes what is being written (for error message creation) + * @param f pointer to a double + * @return the write spec + */ +struct GNUNET_BIO_WriteSpec +GNUNET_BIO_write_spec_double (const char *what, double *f); + + +/** + * Execute the write specifications in order. + * + * @param h the IO handle to write to + * @param ws array of write specs + * the last element must be #GNUNET_BIO_write_spec_end + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_BIO_write_spec_commit (struct GNUNET_BIO_WriteHandle *h, + struct GNUNET_BIO_WriteSpec *ws); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_BIO_LIB_H */ +#endif + +/** @} */ /* end of group bio */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_bio_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_buffer_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_buffer_lib.h @@ -0,0 +1,215 @@ +/* + This file is part of GNUnet. + Copyright (C) 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 + */ + +/** + * @addtogroup libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * Common buffer management functions. + * + * @author Florian Dold + */ + +#if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_BUFFER_LIB_H +#define GNUNET_BUFFER_LIB_H + +/** + * Dynamically growing buffer. Can be used to construct + * strings and other objects with dynamic size. + * + * This structure should, in most cases, be stack-allocated and + * zero-initialized, like: + * + * struct GNUNET_Buffer my_buffer = { 0 }; + */ +struct GNUNET_Buffer +{ + /** + * Capacity of the buffer. + */ + size_t capacity; + + /** + * Current write position. + */ + size_t position; + + /** + * Backing memory. + */ + char *mem; + + /** + * Log a warning if the buffer is grown over its initially allocated capacity. + */ + int warn_grow; +}; + + +/** + * Initialize a buffer with the given capacity. + * + * When a buffer is allocated with this function, a warning is logged + * when the buffer exceeds the initial capacity. + * + * @param buf the buffer to initialize + * @param capacity the capacity (in bytes) to allocate for @a buf + */ +void +GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity); + + +/** + * Make sure that at least @a n bytes remaining in the buffer. + * + * @param buf buffer to potentially grow + * @param n number of bytes that should be available to write + */ +void +GNUNET_buffer_ensure_remaining (struct GNUNET_Buffer *buf, size_t n); + + +/** + * Write bytes to the buffer. + * + * Grows the buffer if necessary. + * + * @param buf buffer to write to + * @param data data to read from + * @param len number of bytes to copy from @a data to @a buf + * + */ +void +GNUNET_buffer_write (struct GNUNET_Buffer *buf, const char *data, size_t len); + + +/** + * Write a 0-terminated string to a buffer, excluding the 0-terminator. + * + * Grows the buffer if necessary. + * + * @param buf the buffer to write to + * @param str the string to write to @a buf + */ +void +GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str); + + +/** + * Write data encoded via #GNUNET_STRINGS_data_to_string to the buffer. + * + * Grows the buffer if necessary. + * + * @param buf buffer to write to + * @param data data to read from + * @param data_len number of bytes to copy from @a data to @a buf + */ +void +GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf, + const void *data, + size_t data_len); + + +/** + * Write a path component to a buffer, ensuring that + * there is exactly one slash between the previous contents + * of the buffer and the new string. + * + * @param buf buffer to write to + * @param str string containing the new path component + */ +void +GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str); + + +/** + * Write a 0-terminated formatted string to a buffer, excluding the + * 0-terminator. + * + * Grows the buffer if necessary. + * + * @param buf the buffer to write to + * @param fmt format string + * @param ... format arguments + */ +void +GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...) +__attribute__ ((format (printf, 2, 3))); + + +/** + * Write a 0-terminated formatted string to a buffer, excluding the + * 0-terminator. + * + * Grows the buffer if necessary. + * + * @param buf the buffer to write to + * @param fmt format string + * @param args format argument list + */ +void +GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf, const char *fmt, va_list + args); + + +/** + * Clear the buffer and return the string it contained. + * The caller is responsible to eventually #GNUNET_free + * the returned string. + * + * The returned string is always 0-terminated. + * + * @param buf the buffer to reap the string from + * @returns the buffer contained in the string + */ +char * +GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf); + + +/** + * Clear the buffer and return its contents. + * The caller is responsible to eventually #GNUNET_free + * the returned data. + * + * @param buf the buffer to reap the contents from + * @param size where to store the size of the returned data + * @returns the data contained in the string + */ +void * +GNUNET_buffer_reap (struct GNUNET_Buffer *buf, size_t *size); + + +/** + * Free the backing memory of the given buffer. + * Does not free the memory of the buffer control structure, + * which is typically stack-allocated. + */ +void +GNUNET_buffer_clear (struct GNUNET_Buffer *buf); + + +#endif + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_child_management_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_child_management_lib.h @@ -0,0 +1,81 @@ +/* + This file is part of GNUnet + Copyright (C) 2021 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 + * @{ + * + * @file include/gnunet_child_management_lib.h + * @brief GNUnet child management api + * @author Christian Grothoff + * @author Dominik Meister + * @author Dennis Neufeld + * @author t3sserakt + */ +#ifndef GNUNET_CHILD_MANAGEMENT_LIB_H +#define GNUNET_CHILD_MANAGEMENT_LIB_H + +/** + * Handle for the child management + */ +struct GNUNET_ChildWaitHandle; + +/** + * Defines a GNUNET_ChildCompletedCallback which is sent back + * upon death or completion of a child process. + * + * @param cls handle for the callback + * @param type type of the process + * @param exit_code status code of the process + */ +typedef void +(*GNUNET_ChildCompletedCallback)(void *cls, + enum GNUNET_OS_ProcessStatusType type, + long unsigned int exit_code); + +/** + * Starts the handling of the child processes. + * Function checks the status of the child process and sends back a + * GNUNET_ChildCompletedCallback upon completion/death of the child. + * + * @param proc child process which is monitored + * @param cb reference to the callback which is called after completion + * @param cb_cls closure for the callback + * @return GNUNET_ChildWaitHandle is returned + */ +struct GNUNET_ChildWaitHandle * +GNUNET_wait_child (struct GNUNET_OS_Process *proc, + GNUNET_ChildCompletedCallback cb, + void *cb_cls); + +/** + * Stop waiting on this child. + */ +void +GNUNET_wait_child_cancel (struct GNUNET_ChildWaitHandle *cwh); + +#endif + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_client_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_client_lib.h @@ -0,0 +1,113 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-2013, 2016 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 + * @{ + * + * @addtogroup networking + * @{ + * + * @author Christian Grothoff + * + * @file + * Functions related to accessing services + + * @defgroup client Client library + * Generic client-side communication with services + * + * @see [Documentation](https://gnunet.org/ipc) + * + * @{ + */ + +#if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_CLIENT_LIB_H +#define GNUNET_CLIENT_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_mq_lib.h" + + +/** + * Test if the port or UNIXPATH of the given @a service_name + * is in use and thus (most likely) the respective service is up. + * + * @param cfg our configuration + * @param service_name name of the service to connect to + * @return #GNUNET_YES if the service is (likely) up (or running remotely), + * #GNUNET_NO if the service is (definitively) down, + * #GNUNET_SYSERR if the configuration does not give us + * the necessary information about the service, or if + * we could not check (e.g. socket() failed) + */ +int +GNUNET_CLIENT_test (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *service_name); + + +/** + * Create a message queue to connect to a GNUnet service. + * If handlers are specified, receive messages from the connection. + * + * @param cfg our configuration + * @param service_name name of the service to connect to + * @param handlers handlers for receiving messages, can be NULL + * @param error_handler error handler + * @param error_handler_cls closure for the @a error_handler + * @return the message queue, NULL on error + */ +struct GNUNET_MQ_Handle * +GNUNET_CLIENT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *service_name, + const struct GNUNET_MQ_MessageHandler *handlers, + GNUNET_MQ_ErrorHandler error_handler, + void *error_handler_cls); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_CLIENT_LIB_H */ +#endif + +/** @} */ /* end of group client */ + +/** @} */ /* end of group addition */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_client_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_common.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_common.h @@ -0,0 +1,1908 @@ +/* + This file is part of GNUnet. + Copyright (C) 2006-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 libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @file include/gnunet_common.h + * @brief commonly used definitions; globals in this file + * are exempt from the rule that the module name ("common") + * must be part of the symbol name. + * + * @author Christian Grothoff + * @author Nils Durner + * @author Martin Schanzenbach + * + * @defgroup logging Logging + * @see [Documentation](https://gnunet.org/logging) + * + * @defgroup memory Memory management + */ +#ifndef GNUNET_COMMON_H +#define GNUNET_COMMON_H + +#include "gnunet_config.h" + +#include <stdbool.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdint.h> +#include <stdarg.h> +#include <sys/types.h> + +#if defined(__FreeBSD__) + +#include <sys/endian.h> +#define bswap_32(x) bswap32 (x) +#define bswap_64(x) bswap64 (x) + +#elif defined(__OpenBSD__) + +#define bswap_32(x) swap32 (x) +#define bswap_64(x) swap64 (x) + +#elif defined(__NetBSD__) + +#include <machine/bswap.h> +#if defined(__BSWAP_RENAME) && ! defined(__bswap_32) +#define bswap_32(x) bswap32 (x) +#define bswap_64(x) bswap64 (x) +#endif + +#elif defined(__linux__) || defined(GNU) +#include <byteswap.h> +#endif + + +/* This is also included in platform.h, but over there a couple of + GNUnet-specific gettext-related macros are defined in addition to including + the header file. Because this header file uses gettext, this include + statement makes sure gettext macros are defined even when platform.h is + unavailable. */ +#include "gettext.h" + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * Version of the API (for entire gnunetutil.so library). + */ +#define GNUNET_UTIL_VERSION 0x000A0104 + + +/** + * Named constants for return values. The following invariants hold: + * `GNUNET_NO == 0` (to allow `if (GNUNET_NO)`) `GNUNET_OK != + * GNUNET_SYSERR`, `GNUNET_OK != GNUNET_NO`, `GNUNET_NO != + * GNUNET_SYSERR` and finally `GNUNET_YES != GNUNET_NO`. + */ +enum GNUNET_GenericReturnValue +{ + GNUNET_SYSERR = -1, + GNUNET_NO = 0, + GNUNET_OK = 1, + /* intentionally identical to #GNUNET_OK! */ + GNUNET_YES = 1, +}; + + +#define GNUNET_MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#define GNUNET_MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/* some systems use one underscore only, and mingw uses no underscore... */ +#ifndef __BYTE_ORDER +#ifdef _BYTE_ORDER +#define __BYTE_ORDER _BYTE_ORDER +#else +#ifdef BYTE_ORDER +#define __BYTE_ORDER BYTE_ORDER +#endif +#endif +#endif +#ifndef __BIG_ENDIAN +#ifdef _BIG_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN +#else +#ifdef BIG_ENDIAN +#define __BIG_ENDIAN BIG_ENDIAN +#endif +#endif +#endif +#ifndef __LITTLE_ENDIAN +#ifdef _LITTLE_ENDIAN +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#else +#ifdef LITTLE_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#endif +#endif +#endif + +/** + * @ingroup logging + * define #GNUNET_EXTRA_LOGGING if using this header outside the GNUnet source + * tree where gnunet_config.h is unavailable + */ +#ifndef GNUNET_EXTRA_LOGGING +#define GNUNET_EXTRA_LOGGING 1 +#endif + +/** + * Endian operations + */ + +#if defined(bswap_16) || defined(bswap_32) || defined(bswap_64) +#define BYTE_SWAP_16(x) bswap_16 (x) +#define BYTE_SWAP_32(x) bswap_32 (x) +#define BYTE_SWAP_64(x) bswap_64 (x) +#else +#define BYTE_SWAP_16(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8)) + +#define BYTE_SWAP_32(x) \ + ((((x) & 0x000000ffU) << 24) | (((x) & 0x0000ff00U) << 8) \ + | (((x) & 0x00ff0000U) >> 8) | (((x) & 0xff000000U) >> 24)) + +#define BYTE_SWAP_64(x) \ + ((((x) & 0x00000000000000ffUL) << 56) | (((x) & 0x000000000000ff00UL) << \ + 40) \ + | (((x) & 0x0000000000ff0000UL) << 24) | (((x) & 0x00000000ff000000UL) \ + << 8) \ + | (((x) & 0x000000ff00000000UL) >> 8) | (((x) & 0x0000ff0000000000UL) \ + >> 24) \ + | (((x) & 0x00ff000000000000UL) >> 40) | (((x) & 0xff00000000000000UL) \ + >> \ + 56)) +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define GNUNET_htobe16(x) BYTE_SWAP_16 (x) +#define GNUNET_htole16(x) (x) +#define GNUNET_be16toh(x) BYTE_SWAP_16 (x) +#define GNUNET_le16toh(x) (x) + +#define GNUNET_htobe32(x) BYTE_SWAP_32 (x) +#define GNUNET_htole32(x) (x) +#define GNUNET_be32toh(x) BYTE_SWAP_32 (x) +#define GNUNET_le32toh(x) (x) + +#define GNUNET_htobe64(x) BYTE_SWAP_64 (x) +#define GNUNET_htole64(x) (x) +#define GNUNET_be64toh(x) BYTE_SWAP_64 (x) +#define GNUNET_le64toh(x) (x) +#endif +#if __BYTE_ORDER == __BIG_ENDIAN +#define GNUNET_htobe16(x) (x) +#define GNUNET_htole16(x) BYTE_SWAP_16 (x) +#define GNUNET_be16toh(x) (x) +#define GNUNET_le16toh(x) BYTE_SWAP_16 (x) + +#define GNUNET_htobe32(x) (x) +#define GNUNET_htole32(x) BYTE_SWAP_32 (x) +#define GNUNET_be32toh(x) (x) +#define GNUNET_le32toh(x) BYTE_SWAP_32 (x) + +#define GNUNET_htobe64(x) (x) +#define GNUNET_htole64(x) BYTE_SWAP_64 (x) +#define GNUNET_be64toh(x) (x) +#define GNUNET_le64toh(x) BYTE_SWAP_64 (x) +#endif + + +/** + * Macro used to avoid using 0 for the length of a variable-size + * array (Non-Zero-Length). + * + * Basically, C standard says that "int[n] x;" is undefined if n=0. + * This was supposed to prevent issues with pointer aliasing. + * However, C compilers may conclude that n!=0 as n=0 would be + * undefined, and then optimize under the assumption n!=0, which + * could cause actual issues. Hence, when initializing an array + * on the stack with a variable-length that might be zero, write + * "int[GNUNET_NZL(n)] x;" instead of "int[n] x". + */ +#define GNUNET_NZL(l) GNUNET_MAX (1, l) + + +/** + * gcc-ism to get packed structs. + */ +#define GNUNET_PACKED __attribute__ ((packed)) + +/** + * gcc-ism to get gcc bitfield layout when compiling with -mms-bitfields + */ +#define GNUNET_GCC_STRUCT_LAYOUT + +/** + * gcc-ism to force alignment; we use this to align char-arrays + * that may then be cast to 'struct's. See also gcc + * bug #33594. + */ +#ifdef __BIGGEST_ALIGNMENT__ +#define GNUNET_ALIGN __attribute__ ((aligned (__BIGGEST_ALIGNMENT__))) +#else +#define GNUNET_ALIGN __attribute__ ((aligned (8))) +#endif + +/** + * gcc-ism to document unused arguments + */ +#define GNUNET_UNUSED __attribute__ ((unused)) + +/** + * gcc-ism to document functions that don't return + */ +#define GNUNET_NORETURN __attribute__ ((noreturn)) + +/** + * Define as empty, GNUNET_PACKED should suffice, but this won't work on W32 + */ +#define GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Define as empty, GNUNET_PACKED should suffice, but this won't work on W32; + */ +#define GNUNET_NETWORK_STRUCT_END + +/* ************************ super-general types *********************** */ + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * @brief A 512-bit hashcode. These are the default length for GNUnet, using SHA-512. + */ +struct GNUNET_HashCode +{ + uint32_t bits[512 / 8 / sizeof(uint32_t)]; /* = 16 */ +}; + + +/** + * @brief A 256-bit hashcode. Used under special conditions, like when space + * is critical and security is not impacted by it. + */ +struct GNUNET_ShortHashCode +{ + uint32_t bits[256 / 8 / sizeof(uint32_t)]; /* = 8 */ +}; + + +/** + * A UUID, a 128 bit "random" value. We OFTEN use + * timeflakes (see: https://github.com/anthonynsimon/timeflake), + * where only 80 bits are random and the rest encodes + * a timestamp to improve database access. + * + * See #GNUNET_CRYPTO_random_timeflake(). + */ +struct GNUNET_Uuid +{ + /** + * 128 random bits. + */ + uint32_t value[4]; +}; + + +/** + * Header for all communications. + */ +struct GNUNET_MessageHeader +{ + /** + * The length of the struct (in bytes, including the length field itself), + * in big-endian format. + */ + uint16_t size GNUNET_PACKED; + + /** + * The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format. + */ + uint16_t type GNUNET_PACKED; +}; + + +/** + * Answer from service to client about last operation. + */ +struct GNUNET_OperationResultMessage +{ + struct GNUNET_MessageHeader header; + + uint32_t reserved GNUNET_PACKED; + + /** + * Operation ID. + */ + uint64_t op_id GNUNET_PACKED; + + /** + * Status code for the operation. + */ + uint64_t result_code GNUNET_PACKED; + + /* Followed by data. */ +}; + + +/** + * Identifier for an asynchronous execution context. + */ +struct GNUNET_AsyncScopeId +{ + uint32_t bits[16 / sizeof(uint32_t)]; /* = 16 bytes */ +}; + +GNUNET_NETWORK_STRUCT_END + + +/** + * Saved async scope identifier or root scope. + */ +struct GNUNET_AsyncScopeSave +{ + /** + * Saved scope. Unused if 'have_scope==GNUNET_NO'. + */ + struct GNUNET_AsyncScopeId scope_id; + + /** + * GNUNET_YES unless this saved scope is the unnamed root scope. + */ + int have_scope; +}; + + +/** + * Function called with a filename. + * + * @param cls closure + * @param filename complete filename (absolute path) + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to stop iteration with no error, + * #GNUNET_SYSERR to abort iteration with error! + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_FileNameCallback) (void *cls, + const char *filename); + + +/** + * Generic continuation callback. + * + * @param cls Closure. + */ +typedef void +(*GNUNET_ContinuationCallback) (void *cls); + + +/** + * Function called with the result of an asynchronous operation. + * + * @param cls + * Closure. + * @param result_code + * Result code for the operation. + * @param data + * Data result for the operation. + * @param data_size + * Size of @a data. + */ +typedef void +(*GNUNET_ResultCallback) (void *cls, + int64_t result_code, + const void *data, + uint16_t data_size); + + +/* ****************************** logging ***************************** */ + +/** + * @ingroup logging + * Types of errors. + */ +enum GNUNET_ErrorType +{ + GNUNET_ERROR_TYPE_UNSPECIFIED = -1, + GNUNET_ERROR_TYPE_NONE = 0, + GNUNET_ERROR_TYPE_ERROR = 1, + GNUNET_ERROR_TYPE_WARNING = 2, + /* UX: We need a message type that is output by + * default without looking like there is a problem. + */ + GNUNET_ERROR_TYPE_MESSAGE = 4, + GNUNET_ERROR_TYPE_INFO = 8, + GNUNET_ERROR_TYPE_DEBUG = 16, + GNUNET_ERROR_TYPE_INVALID = 32, + GNUNET_ERROR_TYPE_BULK = 64 +}; + + +/** + * @ingroup logging + * User-defined handler for log messages. + * + * @param cls closure + * @param kind severeity + * @param component what component is issuing the message? + * @param date when was the message logged? + * @param message what is the message + */ +typedef void +(*GNUNET_Logger) (void *cls, + enum GNUNET_ErrorType kind, + const char *component, + const char *date, + const char *message); + + +/** + * @ingroup logging + * Get the number of log calls that are going to be skipped + * + * @return number of log calls to be ignored + */ +int +GNUNET_get_log_skip (void); + + +#if ! defined(GNUNET_CULL_LOGGING) +int +GNUNET_get_log_call_status (int caller_level, + const char *comp, + const char *file, + const char *function, + int line); + +#endif + +/* *INDENT-OFF* */ +/** + * @ingroup logging + * Main log function. + * + * @param kind how serious is the error? + * @param message what is the message (format string) + * @param ... arguments for format string + */ +void +GNUNET_log_nocheck (enum GNUNET_ErrorType kind, + const char *message, + ...) +__attribute__ ((format (printf, 2, 3))); + +/* from glib */ +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +#define _GNUNET_BOOLEAN_EXPR(expr) \ + __extension__ ({ \ + int _gnunet_boolean_var_; \ + if (expr) \ + _gnunet_boolean_var_ = 1; \ + else \ + _gnunet_boolean_var_ = 0; \ + _gnunet_boolean_var_; \ + }) +#define GN_LIKELY(expr) (__builtin_expect (_GNUNET_BOOLEAN_EXPR (expr), 1)) +#define GN_UNLIKELY(expr) (__builtin_expect (_GNUNET_BOOLEAN_EXPR (expr), 0)) +#else +#define GN_LIKELY(expr) (expr) +#define GN_UNLIKELY(expr) (expr) +#endif + +#if ! defined(GNUNET_LOG_CALL_STATUS) +#define GNUNET_LOG_CALL_STATUS -1 +#endif +/* *INDENT-ON* */ + + +/** + * @ingroup logging + * Log function that specifies an alternative component. + * This function should be used by plugins. + * + * @param kind how serious is the error? + * @param comp component responsible for generating the message + * @param message what is the message (format string) + * @param ... arguments for format string + */ +void +GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, + const char *comp, + const char *message, + ...) +__attribute__ ((format (printf, 3, 4))); + +#if ! defined(GNUNET_CULL_LOGGING) +#define GNUNET_log_from(kind, comp, ...) \ + do \ + { \ + static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ + if ((GNUNET_EXTRA_LOGGING > 0) || \ + ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ + { \ + if (GN_UNLIKELY (log_call_enabled == -1)) \ + log_call_enabled = \ + GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \ + (comp), \ + __FILE__, \ + __FUNCTION__, \ + __LINE__); \ + if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ + { \ + GNUNET_log_skip (-1, GNUNET_NO); \ + } \ + else \ + { \ + if (GN_UNLIKELY (log_call_enabled)) \ + GNUNET_log_from_nocheck ((kind), comp, __VA_ARGS__); \ + } \ + } \ + } while (0) + +#define GNUNET_log(kind, ...) \ + do \ + { \ + static int log_call_enabled = GNUNET_LOG_CALL_STATUS; \ + if ((GNUNET_EXTRA_LOGGING > 0) || \ + ((GNUNET_ERROR_TYPE_DEBUG & (kind)) == 0)) \ + { \ + if (GN_UNLIKELY (log_call_enabled == -1)) \ + log_call_enabled = \ + GNUNET_get_log_call_status ((kind) & (~GNUNET_ERROR_TYPE_BULK), \ + NULL, \ + __FILE__, \ + __FUNCTION__, \ + __LINE__); \ + if (GN_UNLIKELY (GNUNET_get_log_skip () > 0)) \ + { \ + GNUNET_log_skip (-1, GNUNET_NO); \ + } \ + else \ + { \ + if (GN_UNLIKELY (log_call_enabled)) \ + GNUNET_log_nocheck ((kind), __VA_ARGS__); \ + } \ + } \ + } while (0) +#else +#define GNUNET_log(...) +#define GNUNET_log_from(...) +#endif + + +/** + * @ingroup logging + * Log error message about missing configuration option. + * + * @param kind log level + * @param section section with missing option + * @param option name of missing option + */ +void +GNUNET_log_config_missing (enum GNUNET_ErrorType kind, + const char *section, + const char *option); + + +/** + * @ingroup logging + * Log error message about invalid configuration option value. + * + * @param kind log level + * @param section section with invalid option + * @param option name of invalid option + * @param required what is required that is invalid about the option + */ +void +GNUNET_log_config_invalid (enum GNUNET_ErrorType kind, + const char *section, + const char *option, + const char *required); + + +/** + * @ingroup logging + * Abort the process, generate a core dump if possible. + * Most code should use `GNUNET_assert (0)` instead to + * first log the location of the failure. + */ +void +GNUNET_abort_ (void) GNUNET_NORETURN; + + +/** + * Convert a buffer to an 8-character string + * representative of the contents. This is used + * for logging binary data when debugging. + * + * @param buf buffer to log + * @param buf_size number of bytes in @a buf + * @return text representation of buf, valid until next + * call to this function + */ +const char * +GNUNET_b2s (const void *buf, + size_t buf_size); + + +/** + * Convert a fixed-sized object to a string using + * #GNUNET_b2s(). + * + * @param obj address of object to convert + * @return string representing the binary obj buffer + */ +#define GNUNET_B2S(obj) GNUNET_b2s ((obj), sizeof (*(obj))) + + +/** + * @ingroup logging + * Ignore the next @a n calls to the log function. + * + * @param n number of log calls to ignore (could be negative) + * @param check_reset #GNUNET_YES to assert that the log skip counter is currently zero + */ +void +GNUNET_log_skip (int n, int check_reset); + + +/** + * @ingroup logging + * Setup logging. + * + * @param comp default component to use + * @param loglevel what types of messages should be logged + * @param logfile change logging to logfile (use NULL to keep stderr) + * @return #GNUNET_OK on success, #GNUNET_SYSERR if logfile could not be opened + */ +enum GNUNET_GenericReturnValue +GNUNET_log_setup (const char *comp, + const char *loglevel, + const char *logfile); + + +/** + * @ingroup logging + * Add a custom logger. Note that installing any custom logger + * will disable the standard logger. When multiple custom loggers + * are installed, all will be called. The standard logger will + * only be used if no custom loggers are present. + * + * @param logger log function + * @param logger_cls closure for @a logger + */ +void +GNUNET_logger_add (GNUNET_Logger logger, + void *logger_cls); + + +/** + * @ingroup logging + * Remove a custom logger. + * + * @param logger log function + * @param logger_cls closure for @a logger + */ +void +GNUNET_logger_remove (GNUNET_Logger logger, + void *logger_cls); + + +/** + * @ingroup logging + * Convert a short hash value to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param shc the hash code + * @return string + */ +const char * +GNUNET_sh2s (const struct GNUNET_ShortHashCode *shc); + + +/** + * @ingroup logging + * Convert a UUID to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param uuid the UUID + * @return string + */ +const char * +GNUNET_uuid2s (const struct GNUNET_Uuid *uuid); + + +/** + * @ingroup logging + * Convert a hash value to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param hc the hash code + * @return string + */ +const char * +GNUNET_h2s (const struct GNUNET_HashCode *hc); + + +/** + * @ingroup logging + * Convert a hash value to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! Identical to #GNUNET_h2s(), except that another + * buffer is used so both #GNUNET_h2s() and #GNUNET_h2s2() can be + * used within the same log statement. + * + * @param hc the hash code + * @return string + */ +const char * +GNUNET_h2s2 (const struct GNUNET_HashCode *hc); + + +/** + * @ingroup logging + * Convert a hash value to a string (for printing debug messages). + * This prints all 104 characters of a hashcode! + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param hc the hash code + * @return string + */ +const char * +GNUNET_h2s_full (const struct GNUNET_HashCode *hc); + + +/** + * Public key. Details in gnunet_util_crypto.h. + */ +struct GNUNET_CRYPTO_EddsaPublicKey; + + +/** + * Public key. Details in gnunet_util_crypto.h. + */ +struct GNUNET_CRYPTO_EcdhePublicKey; + + +/** + * @ingroup logging + * Convert a public key value to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param hc the hash code + * @return string + */ +const char * +GNUNET_p2s (const struct GNUNET_CRYPTO_EddsaPublicKey *p); + + +/** + * @ingroup logging + * Convert a public key value to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param hc the hash code + * @return string + */ +const char * +GNUNET_p2s2 (const struct GNUNET_CRYPTO_EddsaPublicKey *p); + + +/** + * @ingroup logging + * Convert a public key value to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param hc the hash code + * @return string + */ +const char * +GNUNET_e2s (const struct GNUNET_CRYPTO_EcdhePublicKey *p); + + +/** + * @ingroup logging + * Convert a public key value to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param hc the hash code + * @return string + */ +const char * +GNUNET_e2s2 (const struct GNUNET_CRYPTO_EcdhePublicKey *p); + + +/** + * Forward declaration to make compiler happy depending on include order. + */ +struct GNUNET_PeerIdentity; + + +/** + * @ingroup logging + * Convert a peer identity to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param pid the peer identity + * @return string form of the pid; will be overwritten by next + * call to #GNUNET_i2s(). + */ +const char * +GNUNET_i2s (const struct GNUNET_PeerIdentity *pid); + + +/** + * @ingroup logging + * Convert a peer identity to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! Identical to #GNUNET_i2s(), except that another + * buffer is used so both #GNUNET_i2s() and #GNUNET_i2s2() can be + * used within the same log statement. + * + * @param pid the peer identity + * @return string form of the pid; will be overwritten by next + * call to #GNUNET_i2s(). + */ +const char * +GNUNET_i2s2 (const struct GNUNET_PeerIdentity *pid); + + +/** + * @ingroup logging + * Convert a peer identity to a string (for printing debug messages). + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param pid the peer identity + * @return string form of the pid; will be overwritten by next + * call to #GNUNET_i2s_full(). + */ +const char * +GNUNET_i2s_full (const struct GNUNET_PeerIdentity *pid); + + +/** + * @ingroup logging + * Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string + * (for printing debug messages). This is one of the very few calls + * in the entire API that is NOT reentrant! + * + * @param addr the address + * @param addrlen the length of the @a addr + * @return nicely formatted string for the address + * will be overwritten by next call to #GNUNET_a2s(). + */ +const char * +GNUNET_a2s (const struct sockaddr *addr, socklen_t addrlen); + + +/** + * @ingroup logging + * Convert error type to string. + * + * @param kind type to convert + * @return string corresponding to the type + */ +const char * +GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); + + +/** + * @ingroup logging + * Use this for fatal errors that cannot be handled + */ +#if __GNUC__ >= 6 || __clang_major__ >= 6 +#define GNUNET_assert(cond) \ + do \ + { \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wtautological-compare\"") \ + if (! (cond)) \ + { \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + dgettext ("gnunet", "Assertion failed at %s:%d. Aborting.\n"), \ + __FILE__, \ + __LINE__); \ + GNUNET_abort_ (); \ + } \ + _Pragma("GCC diagnostic pop") \ + } while (0) +#else +/* older GCC/clangs do not support -Wtautological-compare */ +#define GNUNET_assert(cond) \ + do \ + { \ + if (! (cond)) \ + { \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + dgettext ("gnunet", \ + "Assertion failed at %s:%d. Aborting.\n"), \ + __FILE__, \ + __LINE__); \ + GNUNET_abort_ (); \ + } \ + } while (0) +#endif + +/** + * @ingroup logging + * Use this for fatal errors that cannot be handled + */ +#define GNUNET_assert_at(cond, f, l) \ + do \ + { \ + if (! (cond)) \ + { \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + dgettext ("gnunet", \ + "Assertion failed at %s:%d. Aborting.\n"), \ + f, \ + l); \ + GNUNET_abort_ (); \ + } \ + } while (0) + + +/** + * @ingroup logging + * Use this for fatal errors that cannot be handled + * + * @param cond Condition to evaluate + * @param comp Component string to use for logging + */ +#define GNUNET_assert_from(cond, comp) \ + do \ + { \ + if (! (cond)) \ + { \ + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, \ + comp, \ + dgettext ("gnunet", \ + "Assertion failed at %s:%d. Aborting.\n") \ + , \ + __FILE__, \ + __LINE__); \ + GNUNET_abort_ (); \ + } \ + } while (0) + + +#ifdef _Static_assert +/** + * Assertion to be checked (if supported by C compiler) at + * compile time, otherwise checked at runtime and resulting + * in an abort() on failure. + * + * @param cond condition to test, 0 implies failure + */ +#define GNUNET_static_assert(cond) _Static_assert (cond, "") +#else +/** + * Assertion to be checked (if supported by C compiler) at + * compile time, otherwise checked at runtime and resulting + * in an abort() on failure. This is the case where the + * compiler does not support static assertions. + * + * @param cond condition to test, 0 implies failure + */ +#define GNUNET_static_assert(cond) GNUNET_assert (cond) +#endif + + +/** + * @ingroup logging + * Use this for internal assertion violations that are + * not fatal (can be handled) but should not occur. + */ +#define GNUNET_break(cond) \ + do \ + { \ + if (! (cond)) \ + { \ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \ + dgettext ("gnunet", "Assertion failed at %s:%d.\n"), \ + __FILE__, \ + __LINE__); \ + } \ + } while (0) + + +/** + * @ingroup logging + * Use this for assertion violations caused by other + * peers (i.e. protocol violations). We do not want to + * confuse end-users (say, some other peer runs an + * older, broken or incompatible GNUnet version), but + * we still want to see these problems during + * development and testing. "OP == other peer". + */ +#define GNUNET_break_op(cond) \ + do \ + { \ + if (! (cond)) \ + { \ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, \ + dgettext ("gnunet", \ + "External protocol violation detected at %s:%d.\n"), \ + __FILE__, \ + __LINE__); \ + } \ + } while (0) + + +/** + * @ingroup logging + * Log an error message at log-level 'level' that indicates + * a failure of the command 'cmd' with the message given + * by strerror(errno). + */ +#define GNUNET_log_strerror(level, cmd) \ + do \ + { \ + GNUNET_log (level, \ + dgettext ("gnunet", \ + "`%s' failed at %s:%d with error: %s\n"), \ + cmd, \ + __FILE__, \ + __LINE__, \ + strerror (errno)); \ + } while (0) + + +/** + * @ingroup logging + * Log an error message at log-level 'level' that indicates + * a failure of the command 'cmd' with the message given + * by strerror(errno). + */ +#define GNUNET_log_from_strerror(level, component, cmd) \ + do \ + { \ + GNUNET_log_from (level, \ + component, \ + dgettext ("gnunet", \ + "`%s' failed at %s:%d with error: %s\n"), \ + cmd, \ + __FILE__, \ + __LINE__, \ + strerror (errno)); \ + } while (0) + + +/** + * @ingroup logging + * Log an error message at log-level 'level' that indicates + * a failure of the command 'cmd' with the message given + * by strerror(errno). + */ +#define GNUNET_log_strerror_file(level, cmd, filename) \ + do \ + { \ + GNUNET_log (level, \ + dgettext ("gnunet", \ + "`%s' failed on file `%s' at %s:%d with error: %s\n"), \ + cmd, \ + filename, \ + __FILE__, \ + __LINE__, \ + strerror (errno)); \ + } while (0) + + +/** + * @ingroup logging + * Log an error message at log-level 'level' that indicates + * a failure of the command 'cmd' with the message given + * by strerror(errno). + */ +#define GNUNET_log_from_strerror_file(level, component, cmd, filename) \ + do \ + { \ + GNUNET_log_from (level, \ + component, \ + dgettext ("gnunet", \ + "`%s' failed on file `%s' at %s:%d with error: %s\n"), \ + cmd, \ + filename, \ + __FILE__, \ + __LINE__, \ + strerror (errno)); \ + } while (0) + +/* ************************* endianness conversion ****************** */ + +#ifdef htonbe64 + +#define GNUNET_htonll(n) htobe64 (n) + +#else +/** + * Convert unsigned 64-bit integer to network byte order. + * + * @param n + * The value in host byte order. + * + * @return The same value in network byte order. + */ +uint64_t +GNUNET_htonll (uint64_t n); + +#endif + + +#ifdef be64toh + +#define GNUNET_ntohll(n) be64toh (n) + +#else +/** + * Convert unsigned 64-bit integer to host byte order. + * + * @param n + * The value in network byte order. + * + * @return The same value in host byte order. + */ +uint64_t +GNUNET_ntohll (uint64_t n); + +#endif + + +/** + * Convert double to network byte order. + * + * @param d + * The value in host byte order. + * + * @return The same value in network byte order. + */ +double +GNUNET_hton_double (double d); + + +/** + * Convert double to host byte order + * + * @param d + * The value in network byte order. + * + * @return The same value in host byte order. + */ +double +GNUNET_ntoh_double (double d); + + +/* ************************* allocation functions ****************** */ + +/** + * @ingroup memory + * Maximum allocation with GNUNET_malloc macro. + */ +#define GNUNET_MAX_MALLOC_CHECKED (1024 * 1024 * 40) + +/** + * @ingroup memory + * Allocate a struct or union of the given @a type. + * Wrapper around #GNUNET_malloc that returns a pointer + * to the newly created object of the correct type. + * + * @param type name of the struct or union, i.e. pass 'struct Foo'. + */ +#define GNUNET_new(type) (type *) GNUNET_malloc (sizeof(type)) + + +/** + * Compare memory in @a a and @a b, where both must be of + * the same pointer type. + * + * Do NOT use this function on arrays, it would only compare + * the first element! + */ +#define GNUNET_memcmp(a, b) \ + ({ \ + const typeof (*b) * _a = (a); \ + const typeof (*a) * _b = (b); \ + memcmp (_a, _b, sizeof(*a)); \ + }) + + +/** + * Compare memory in @a b1 and @a b2 in constant time, suitable for private + * data. + * + * @param b1 some buffer of size @a len + * @param b2 another buffer of size @a len + * @param len number of bytes in @a b1 and @a b2 + * @return 0 if buffers are equal, + */ +int +GNUNET_memcmp_ct_ (const void *b1, + const void *b2, + size_t len); + +/** + * Compare memory in @a a and @a b in constant time, suitable for private + * data. Both @a a and @a b must be of the same pointer type. + * + * Do NOT use this function on arrays, it would only compare + * the first element! + */ +#define GNUNET_memcmp_priv(a, b) \ + ({ \ + const typeof (*b) * _a = (a); \ + const typeof (*a) * _b = (b); \ + GNUNET_memcmp_ct_ (_a, _b, sizeof(*a)); \ + }) + + +/** + * Check that memory in @a a is all zeros. @a a must be a pointer. + * + * @param a pointer to @a n bytes which should be tested for the + * entire memory being zero'ed out. + * @param n number of bytes in @a to be tested + * @return true if @a a is zero, false_NO otherwise + */ +bool +GNUNET_is_zero_ (const void *a, + size_t n); + + +/** + * Check that memory in @a a is all zeros. @a a must be a pointer. + * + * @param a pointer to a struct which should be tested for the + * entire memory being zero'ed out. + * @return GNUNET_YES if a is zero, GNUNET_NO otherwise + */ +#define GNUNET_is_zero(a) \ + GNUNET_is_zero_ ((a), sizeof (*(a))) + + +/** + * Call memcpy() but check for @a n being 0 first. In the latter + * case, it is now safe to pass NULL for @a src or @a dst. + * Unlike traditional memcpy(), returns nothing. + * + * @param dst destination of the copy, may be NULL if @a n is zero + * @param src source of the copy, may be NULL if @a n is zero + * @param n number of bytes to copy + */ +#define GNUNET_memcpy(dst, src, n) \ + do \ + { \ + if (0 != n) \ + { \ + (void) memcpy (dst, src, n); \ + } \ + } while (0) + + +/* *INDENT-OFF* */ +/** + * @ingroup memory + * Allocate a size @a n array with structs or unions of the given @a type. + * Wrapper around #GNUNET_malloc that returns a pointer + * to the newly created objects of the correct type. + * + * @param n number of elements in the array + * @param type name of the struct or union, i.e. pass 'struct Foo'. + */ +#define GNUNET_new_array(n, type) ({ \ + GNUNET_assert (SIZE_MAX / sizeof (type) >= n); \ + (type *) GNUNET_malloc ((n) * sizeof(type)); \ + }) +/* *INDENT-ON* */ + +/** + * @ingroup memory + * Allocate a size @a n times @a m array + * with structs or unions of the given @a type. + * + * @param n size of the first dimension + * @param m size of the second dimension + * @param type name of the struct or union, i.e. pass 'struct Foo'. + */ +#define GNUNET_new_array_2d(n, m, type) \ + (type **) GNUNET_xnew_array_2d_ (n, m, sizeof(type), __FILE__, __LINE__) + +/** + * @ingroup memory + * Allocate a size @a n times @a m times @a o array + * with structs or unions of the given @a type. + * + * @param n size of the first dimension + * @param m size of the second dimension + * @param o size of the third dimension + * @param type name of the struct or union, i.e. pass 'struct Foo'. + */ +#define GNUNET_new_array_3d(n, m, o, type) \ + (type ***) GNUNET_xnew_array_3d_ (n, m, o, sizeof(type), __FILE__, \ + __LINE__) + +/** + * @ingroup memory + * Wrapper around malloc. Allocates size bytes of memory. + * The memory will be zero'ed out. + * + * @param size the number of bytes to allocate, must be + * smaller than 40 MB. + * @return pointer to size bytes of memory, never NULL (!) + */ +#define GNUNET_malloc(size) GNUNET_xmalloc_ (size, __FILE__, __LINE__) + +/** + * @ingroup memory + * Allocate and initialize a block of memory. + * + * @param buf data to initialize the block with + * @param size the number of bytes in buf (and size of the allocation) + * @return pointer to size bytes of memory, never NULL (!) + */ +#define GNUNET_memdup(buf, size) GNUNET_xmemdup_ (buf, size, __FILE__, __LINE__) + +/** + * @ingroup memory + * Wrapper around malloc. Allocates size bytes of memory. + * The memory will be zero'ed out. + * + * @param size the number of bytes to allocate + * @return pointer to size bytes of memory, NULL if we do not have enough memory + */ +#define GNUNET_malloc_large(size) \ + GNUNET_xmalloc_unchecked_ (size, __FILE__, __LINE__) + + +/** + * @ingroup memory + * Wrapper around realloc. Reallocates size bytes of memory. + * The content of the intersection of the new and old size will be unchanged. + * + * @param ptr the pointer to reallocate + * @param size the number of bytes to reallocate + * @return pointer to size bytes of memory + */ +#define GNUNET_realloc(ptr, size) \ + GNUNET_xrealloc_ (ptr, size, __FILE__, __LINE__) + + +/** + * @ingroup memory + * Wrapper around free. Frees the memory referred to by ptr. + * Note that it is generally better to free memory that was + * allocated with #GNUNET_array_grow using #GNUNET_array_grow(mem, size, 0) instead of #GNUNET_free_nz. + * + * @param ptr location where to free the memory. ptr must have + * been returned by #GNUNET_strdup, #GNUNET_strndup, #GNUNET_malloc or #GNUNET_array_grow earlier. NULL is allowed. + */ +#define GNUNET_free_nz(ptr) GNUNET_xfree_ (ptr, __FILE__, __LINE__) + + +/** + * @ingroup memory + * Wrapper around free. Frees the memory referred to by ptr and sets ptr to NULL. + * Note that it is generally better to free memory that was + * allocated with #GNUNET_array_grow using #GNUNET_array_grow(mem, size, 0) instead of #GNUNET_free. + * + * @a ptr will be set to NULL. Use #GNUNET_free_nz() if @a ptr is not an L-value. + * + * @param ptr location where to free the memory. ptr must have + * been returned by #GNUNET_strdup, #GNUNET_strndup, #GNUNET_malloc or #GNUNET_array_grow earlier. NULL is allowed. + */ +#define GNUNET_free(ptr) do { \ + GNUNET_xfree_ (ptr, __FILE__, __LINE__); \ + ptr = NULL; \ +} while (0) + + +/** + * @ingroup memory + * Wrapper around #GNUNET_xstrdup_. Makes a copy of the zero-terminated string + * pointed to by a. + * + * @param a pointer to a zero-terminated string + * @return a copy of the string including zero-termination + */ +#define GNUNET_strdup(a) GNUNET_xstrdup_ (a, __FILE__, __LINE__) + + +/** + * @ingroup memory + * Wrapper around #GNUNET_xstrndup_. Makes a partial copy of the string + * pointed to by a. + * + * @param a pointer to a string + * @param length of the string to duplicate + * @return a partial copy of the string including zero-termination + */ +#define GNUNET_strndup(a, length) \ + GNUNET_xstrndup_ (a, length, __FILE__, __LINE__) + +/** + * @ingroup memory + * Grow a well-typed (!) array. This is a convenience + * method to grow a vector @a arr of size @a size + * to the new (target) size @a tsize. + * <p> + * + * Example (simple, well-typed stack): + * + * <pre> + * static struct foo * myVector = NULL; + * static int myVecLen = 0; + * + * static void push(struct foo * elem) { + * GNUNET_array_grow(myVector, myVecLen, myVecLen+1); + * GNUNET_memcpy(&myVector[myVecLen-1], elem, sizeof(struct foo)); + * } + * + * static void pop(struct foo * elem) { + * if (myVecLen == 0) die(); + * GNUNET_memcpy(elem, myVector[myVecLen-1], sizeof(struct foo)); + * GNUNET_array_grow(myVector, myVecLen, myVecLen-1); + * } + * </pre> + * + * @param arr base-pointer of the vector, may be NULL if size is 0; + * will be updated to reflect the new address. The TYPE of + * arr is important since size is the number of elements and + * not the size in bytes + * @param size the number of elements in the existing vector (number + * of elements to copy over), will be updated with the new + * array size + * @param tsize the target size for the resulting vector, use 0 to + * free the vector (then, arr will be NULL afterwards). + */ +#define GNUNET_array_grow(arr, size, tsize) \ + GNUNET_xgrow_ ((void **) &(arr), \ + sizeof((arr)[0]), \ + &size, \ + tsize, \ + __FILE__, \ + __LINE__) + +/** + * @ingroup memory + * Append an element to an array (growing the array by one). + * + * @param arr base-pointer of the vector, may be NULL if @a len is 0; + * will be updated to reflect the new address. The TYPE of + * arr is important since size is the number of elements and + * not the size in bytes + * @param len the number of elements in the existing vector (number + * of elements to copy over), will be updated with the new + * array length + * @param element the element that will be appended to the array + */ +#define GNUNET_array_append(arr, len, element) \ + do \ + { \ + GNUNET_assert ((len) + 1 > (len)); \ + GNUNET_array_grow (arr, len, len + 1); \ + (arr) [len - 1] = element; \ + } while (0) + + +/** + * @ingroup memory + * Append @a arr2 to @a arr1 (growing @a arr1 + * as needed). The @a arr2 array is left unchanged. Naturally + * this function performs a shallow copy. Both arrays must have + * the same type for their elements. + * + * @param arr1 base-pointer of the vector, may be NULL if @a len is 0; + * will be updated to reflect the new address. The TYPE of + * arr is important since size is the number of elements and + * not the size in bytes + * @param len1 the number of elements in the existing vector (number + * of elements to copy over), will be updated with the new + * array size + * @param arr2 base-pointer a second array to concatenate, may be NULL if @a len2 is 0; + * will be updated to reflect the new address. The TYPE of + * arr is important since size is the number of elements and + * not the size in bytes + * @param len2 the number of elements in the existing vector (number + * of elements to copy over), will be updated with the new + * array size + + */ +#define GNUNET_array_concatenate(arr1, len1, arr2, len2) \ + do \ + { \ + const typeof (*arr2) * _a1 = (arr1); \ + const typeof (*arr1) * _a2 = (arr2); \ + GNUNET_assert ((len1) + (len2) >= (len1)); \ + GNUNET_assert (SIZE_MAX / sizeof (*_a1) >= ((len1) + (len2))); \ + GNUNET_array_grow (arr1, len1, (len1) + (len2)); \ + memcpy (&(arr1) [(len1) - (len2)], _a2, (len2) * sizeof (*arr1)); \ + } while (0) + + +/** + * @ingroup memory + * Like snprintf, just aborts if the buffer is of insufficient size. + * + * @param buf pointer to buffer that is written to + * @param size number of bytes in @a buf + * @param format format strings + * @param ... data for format string + * @return number of bytes written to buf or negative value on error + */ +int +GNUNET_snprintf (char *buf, + size_t size, + const char *format, + ...) +__attribute__ ((format (printf, 3, 4))); + + +/** + * @ingroup memory + * Like asprintf, just portable. + * + * @param buf set to a buffer of sufficient size (allocated, caller must free) + * @param format format string (see printf, fprintf, etc.) + * @param ... data for format string + * @return number of bytes in "*buf" excluding 0-termination + */ +int +GNUNET_asprintf (char **buf, + const char *format, + ...) +__attribute__ ((format (printf, 2, 3))); + + +/* ************** internal implementations, use macros above! ************** */ + +/** + * Allocate memory. Checks the return value, aborts if no more + * memory is available. Don't use GNUNET_xmalloc_ directly. Use the + * #GNUNET_malloc macro. + * The memory will be zero'ed out. + * + * @param size number of bytes to allocate + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return allocated memory, never NULL + */ +void * +GNUNET_xmalloc_ (size_t size, + const char *filename, + int linenumber); + + +/** + * Allocate memory for a two dimensional array in one block + * and set up pointers. Aborts if no more memory is available. + * Don't use GNUNET_xnew_array_2d_ directly. Use the + * #GNUNET_new_array_2d macro. + * The memory of the elements will be zero'ed out. + * + * @param n size of the first dimension + * @param m size of the second dimension + * @param elementSize size of a single element in bytes + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return allocated memory, never NULL + */ +void ** +GNUNET_xnew_array_2d_ (size_t n, + size_t m, + size_t elementSize, + const char *filename, + int linenumber); + + +/** + * Allocate memory for a three dimensional array in one block + * and set up pointers. Aborts if no more memory is available. + * Don't use GNUNET_xnew_array_3d_ directly. Use the + * #GNUNET_new_array_3d macro. + * The memory of the elements will be zero'ed out. + * + * @param n size of the first dimension + * @param m size of the second dimension + * @param o size of the third dimension + * @param elementSize size of a single element in bytes + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return allocated memory, never NULL + */ +void *** +GNUNET_xnew_array_3d_ (size_t n, + size_t m, + size_t o, + size_t elementSize, + const char *filename, + int linenumber); + + +/** + * Allocate and initialize memory. Checks the return value, aborts if no more + * memory is available. Don't use GNUNET_xmemdup_ directly. Use the + * #GNUNET_memdup macro. + * + * @param buf buffer to initialize from (must contain size bytes) + * @param size number of bytes to allocate + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return allocated memory, never NULL + */ +void * +GNUNET_xmemdup_ (const void *buf, + size_t size, + const char *filename, + int linenumber); + + +/** + * Allocate memory. This function does not check if the allocation + * request is within reasonable bounds, allowing allocations larger + * than 40 MB. If you don't expect the possibility of very large + * allocations, use #GNUNET_malloc instead. The memory will be zero'ed + * out. + * + * @param size number of bytes to allocate + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return pointer to size bytes of memory, NULL if we do not have enough memory + */ +void * +GNUNET_xmalloc_unchecked_ (size_t size, + const char *filename, + int linenumber); + + +/** + * Reallocate memory. Checks the return value, aborts if no more + * memory is available. + */ +void * +GNUNET_xrealloc_ (void *ptr, + size_t n, + const char *filename, + int linenumber); + + +/** + * Free memory. Merely a wrapper for the case that we + * want to keep track of allocations. Don't use GNUNET_xfree_ + * directly. Use the #GNUNET_free macro. + * + * @param ptr pointer to memory to free + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + */ +void +GNUNET_xfree_ (void *ptr, + const char *filename, + int linenumber); + + +/** + * Dup a string. Don't call GNUNET_xstrdup_ directly. Use the #GNUNET_strdup macro. + * @param str string to duplicate + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return the duplicated string + */ +char * +GNUNET_xstrdup_ (const char *str, + const char *filename, + int linenumber); + +/** + * Dup partially a string. Don't call GNUNET_xstrndup_ directly. Use the #GNUNET_strndup macro. + * + * @param str string to duplicate + * @param len length of the string to duplicate + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + * @return the duplicated string + */ +char * +GNUNET_xstrndup_ (const char *str, + size_t len, + const char *filename, + int linenumber); + +/** + * Grow an array, the new elements are zeroed out. + * Grows old by (*oldCount-newCount)*elementSize + * bytes and sets *oldCount to newCount. + * + * Don't call GNUNET_xgrow_ directly. Use the #GNUNET_array_grow macro. + * + * @param old address of the pointer to the array + * *old may be NULL + * @param elementSize the size of the elements of the array + * @param oldCount address of the number of elements in the *old array + * @param newCount number of elements in the new array, may be 0 (then *old will be NULL afterwards) + * @param filename where is this call being made (for debugging) + * @param linenumber line where this call is being made (for debugging) + */ +void +GNUNET_xgrow_ (void **old, + size_t elementSize, + unsigned int *oldCount, + unsigned int newCount, + const char *filename, + int linenumber); + + +/** + * @ingroup memory + * Create a copy of the given message. + * + * @param msg message to copy + * @return duplicate of the message + */ +struct GNUNET_MessageHeader * +GNUNET_copy_message (const struct GNUNET_MessageHeader *msg); + + +/** + * Set the async scope for the current thread. + * + * @param aid the async scope identifier + * @param[out] old_scope location to save the old scope + */ +void +GNUNET_async_scope_enter (const struct GNUNET_AsyncScopeId *aid, + struct GNUNET_AsyncScopeSave *old_scope); + + +/** + * Clear the current thread's async scope. + * + * @param old_scope scope to restore + */ +void +GNUNET_async_scope_restore (struct GNUNET_AsyncScopeSave *old_scope); + + +/** + * Get the current async scope. + * + * @param[out] scope_ret pointer to where the result is stored + */ +void +GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret); + + +/** + * Generate a fresh async scope identifier. + * + * @param[out] aid_ret pointer to where the result is stored + */ +void +GNUNET_async_scope_fresh (struct GNUNET_AsyncScopeId *aid_ret); + + +#if __STDC_VERSION__ < 199901L +#if __GNUC__ >= 2 +#define __func__ __FUNCTION__ +#else +#define __func__ "<unknown>" +#endif +#endif + + +/** + * Valid task priorities. Use these, do not pass random integers! + * For various reasons (#3862 -- building with QT Creator, and + * our restricted cross-compilation with emscripten) this cannot + * be in gnunet_scheduler_lib.h, but it works if we declare it here. + * Naturally, logically this is part of the scheduler. + */ +enum GNUNET_SCHEDULER_Priority +{ + /** + * Run with the same priority as the current job. + */ + GNUNET_SCHEDULER_PRIORITY_KEEP = 0, + + /** + * Run when otherwise idle. + */ + GNUNET_SCHEDULER_PRIORITY_IDLE = 1, + + /** + * Run as background job (higher than idle, + * lower than default). + */ + GNUNET_SCHEDULER_PRIORITY_BACKGROUND = 2, + + /** + * Run with the default priority (normal + * P2P operations). Any task that is scheduled + * without an explicit priority being specified + * will run with this priority. + */ + GNUNET_SCHEDULER_PRIORITY_DEFAULT = 3, + + /** + * Run with high priority (important requests). + * Higher than DEFAULT. + */ + GNUNET_SCHEDULER_PRIORITY_HIGH = 4, + + /** + * Run with priority for interactive tasks. + * Higher than "HIGH". + */ + GNUNET_SCHEDULER_PRIORITY_UI = 5, + + /** + * Run with priority for urgent tasks. Use + * for things like aborts and shutdowns that + * need to preempt "UI"-level tasks. + * Higher than "UI". + */ + GNUNET_SCHEDULER_PRIORITY_URGENT = 6, + + /** + * This is an internal priority level that is only used for tasks + * that are being triggered due to shutdown (they have automatically + * highest priority). User code must not use this priority level + * directly. Tasks run with this priority level that internally + * schedule other tasks will see their original priority level + * be inherited (unless otherwise specified). + */ + GNUNET_SCHEDULER_PRIORITY_SHUTDOWN = 7, + + /** + * Number of priorities (must be the last priority). + * This priority must not be used by clients. + */ + GNUNET_SCHEDULER_PRIORITY_COUNT = 8 +}; + + +/* *INDENT-OFF* */ + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GNUNET_COMMON_H */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_config.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_config.h @@ -0,0 +1,58 @@ +/* + 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 + */ + +#ifndef GNUNET_CONFIG_H +#define GNUNET_CONFIG_H + +/** + * @author Martin Schanzenbach + * + * @file + * Convenience header including public (!) information on the + * installed GNUnet configuration. + * + */ + +/* The version of GNUnet */ +#define GNUNET_VERSION "0.21.1-145-g8bfe56861" + +/* Major version */ +#define GNUNET_MAJOR_VERSION 0 + +/* Micro version */ +#define GNUNET_MINOR_VERSION 21 + +/* Mico version */ +#define GNUNET_MICRO_VERSION 1 + +/* Set to 1 is this is an experimental build */ +#define GNUNET_EXPERIMENTAL 1 + +/* Set to 1 if GnuTLS has DANE support */ +#define GNUNET_CURL_GNUTLS 0 + +/** + * Set to 1 if file-sharing meta data parsing is built with + * libextractor, which means that callers to the API must use also use + * libextractor. + */ +#define GNUNET_FS_EXTRACTOR_ENABLED 0 + +#endif diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_configuration_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_configuration_lib.h @@ -0,0 +1,818 @@ +/* + This file is part of GNUnet. + Copyright (C) 2006, 2008, 2009, 2018 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 + * Configuration API + * + * @defgroup configuration Configuration library + * Configuration management + * @{ + */ +#ifndef GNUNET_CONFIGURATION_LIB_H +#define GNUNET_CONFIGURATION_LIB_H + + +#include "gnunet_time_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * A configuration object. + */ +struct GNUNET_CONFIGURATION_Handle; + +/** + * Create a new configuration object. + * @return fresh configuration object + */ +struct GNUNET_CONFIGURATION_Handle * +GNUNET_CONFIGURATION_create (void); + + +/** + * Duplicate an existing configuration object. + * + * @param cfg configuration to duplicate + * @return duplicate configuration + */ +struct GNUNET_CONFIGURATION_Handle * +GNUNET_CONFIGURATION_dup ( + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Destroy configuration object. + * + * @param cfg configuration to destroy + */ +void +GNUNET_CONFIGURATION_destroy ( + struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Load configuration. This function will first parse the + * defaults and then parse the specific configuration file + * to overwrite the defaults. + * + * @param cfg configuration to update + * @param filename name of the configuration file, NULL to load defaults + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_load ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *filename); + + +/** + * Load default configuration. This function will parse the + * defaults from the given @a defaults_d directory. + * + * @param cfg configuration to update + * @param defaults_d directory with the defaults + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_load_from ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *defaults_d); + + +/** + * Return GNUnet's default configuration. A new configuration is allocated + * each time and it's up to the caller to destroy it when done. This function + * returns GNUnet's configuration even when #GNUNET_OS_init has been called + * with a value different from #GNUNET_OS_project_data_default. + * + * @return a freshly allocated configuration + */ +struct GNUNET_CONFIGURATION_Handle * +GNUNET_CONFIGURATION_default (void); + + +/** + * Return the filename of the default configuration filename + * that is used when no explicit configuration entry point + * has been specified. + * + * @returns NULL if no default configuration file can be located, + * a newly allocated string otherwise + */ +char * +GNUNET_CONFIGURATION_default_filename (void); + + +/** + * Parse a configuration file, add all of the options in the + * file to the configuration environment. + * + * @param cfg configuration to update + * @param filename name of the configuration file + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_parse ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *filename); + + +/** + * Serializes the given configuration. + * + * @param cfg configuration to serialize + * @param size will be set to the size of the serialized memory block + * @return the memory block where the serialized configuration is + * present. This memory should be freed by the caller + */ +char * +GNUNET_CONFIGURATION_serialize ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + size_t *size); + + +/** + * Serializes the given configuration with diagnostics information. + * Diagnostics information will only be available if diagnostics + * have been enabled before parsing. + * + * @param cfg configuration to serialize + * @return the memory block where the serialized configuration is + * present. This memory should be freed by the caller + */ +char * +GNUNET_CONFIGURATION_serialize_diagnostics ( + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * De-serializes configuration + * + * @param cfg configuration to update + * @param mem the memory block of serialized configuration + * @param size the size of the memory block + * @param source_filename source filename, will be used + * to resolve relative \@INLINE\@ statements + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_deserialize ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *mem, + size_t size, + const char *source_filename); + + +/** + * Write configuration file. + * + * @param cfg configuration to write + * @param filename where to write the configuration + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_write ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *filename); + + +/** + * Write only configuration entries that have been changed to configuration file + * + * @param cfg_default default configuration + * @param cfg_new new configuration + * @param filename where to write the configuration diff between default and new + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_write_diffs ( + const struct GNUNET_CONFIGURATION_Handle *cfg_default, + const struct GNUNET_CONFIGURATION_Handle *cfg_new, + const char *filename); + + +/** + * Compute configuration with only entries that have been changed + * + * @param cfg_default original configuration + * @param cfg_new new configuration + * @return configuration with only the differences, never NULL + */ +struct GNUNET_CONFIGURATION_Handle * +GNUNET_CONFIGURATION_get_diff ( + const struct GNUNET_CONFIGURATION_Handle *cfg_default, + const struct GNUNET_CONFIGURATION_Handle *cfg_new); + + +/** + * Test if there are configuration options that were + * changed since the last save. + * + * @param cfg configuration to inspect + * @return #GNUNET_NO if clean, #GNUNET_YES if dirty, #GNUNET_SYSERR on error (i.e. last save failed) + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_is_dirty ( + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Signature of a function to be run with a configuration. + * + * @param cls closure + * @param cfg the configuration + * @return status code + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_CONFIGURATION_Callback)( + void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Parse a configuration file @a filename and run the function + * @a cb with the resulting configuration object. Then free the + * configuration object and return the status value from @a cb. + * + * @param filename configuration to parse, NULL for "default" + * @param cb function to run + * @param cb_cls closure for @a cb + * @return #GNUNET_SYSERR if parsing the configuration failed, + * otherwise return value from @a cb. + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_parse_and_run ( + const char *filename, + GNUNET_CONFIGURATION_Callback cb, + void *cb_cls); + +/** + * Enable extra diagnostics. Will produce more log output + * and allocate more memory. + * + * @param cfg configuration handle + */ +void +GNUNET_CONFIGURATION_enable_diagnostics ( + struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Function to iterate over options. + * + * @param cls closure + * @param section name of the section + * @param option name of the option + * @param value value of the option + */ +typedef void +(*GNUNET_CONFIGURATION_Iterator) (void *cls, + const char *section, + const char *option, + const char *value); + + +/** + * Function to iterate over section. + * + * @param cls closure + * @param section name of the section + */ +typedef void +(*GNUNET_CONFIGURATION_SectionIterator) (void *cls, + const char *section); + + +/** + * Iterate over all options in the configuration. + * + * @param cfg configuration to inspect + * @param iter function to call on each option + * @param iter_cls closure for @a iter + */ +void +GNUNET_CONFIGURATION_iterate ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_CONFIGURATION_Iterator iter, + void *iter_cls); + + +/** + * Iterate over all sections in the configuration. + * + * @param cfg configuration to inspect + * @param iter function to call on each section + * @param iter_cls closure for @a iter + */ +void +GNUNET_CONFIGURATION_iterate_sections ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_CONFIGURATION_SectionIterator iter, + void *iter_cls); + + +/** + * Remove the given section and all options in it. + * + * @param cfg configuration to inspect + * @param section name of the section to remove + */ +void +GNUNET_CONFIGURATION_remove_section ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section); + + +/** + * Get a configuration value that should be a number. + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param number where to store the numeric value of the option + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_number ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + unsigned long long *number); + + +/** + * Get a configuration value that should be a floating point number. + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param number where to store the floating value of the option + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_float ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + float *number); + + +/** + * Get a configuration value that should be a relative time. + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param time set to the time value stored in the configuration + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_time ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + struct GNUNET_TIME_Relative *time); + + +/** + * Get a configuration value that should be a size in bytes. + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param size set to the size in bytes as stored in the configuration + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_size ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + unsigned long long *size); + + +/** + * Test if we have a value for a particular option + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @return #GNUNET_YES if so, #GNUNET_NO if not. + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option); + + +/** + * Get a configuration value that should be a string. + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param value will be set to a freshly allocated configuration + * value, or NULL if option is not specified + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_string ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + char **value); + + +/** + * Get a configuration value that should be the name of a file + * or directory. + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param value will be set to a freshly allocated configuration + * value, or NULL if option is not specified + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_filename ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + char **value); + + +/** + * Iterate over the set of filenames stored in a configuration value. + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param cb function to call on each filename + * @param cb_cls closure for @a cb + * @return number of filenames iterated over, -1 on error + */ +int +GNUNET_CONFIGURATION_iterate_value_filenames ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + GNUNET_FileNameCallback cb, + void *cb_cls); + + +/** + * Iterate over values of a section in the configuration. + * + * @param cfg configuration to inspect + * @param section the section + * @param iter function to call on each option + * @param iter_cls closure for @a iter + */ +void +GNUNET_CONFIGURATION_iterate_section_values ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + GNUNET_CONFIGURATION_Iterator iter, + void *iter_cls); + + +/** + * Get a configuration value that should be in a set of + * predefined strings + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @param choices NULL-terminated list of legal values + * @param value will be set to an entry in the legal list, + * or NULL if option is not specified and no default given + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_choice ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + const char *const *choices, + const char **value); + + +/** + * Get a configuration value that should be in a set of + * "YES" or "NO". + * + * @param cfg configuration to inspect + * @param section section of interest + * @param option option of interest + * @return #GNUNET_YES, #GNUNET_NO or if option has no valid value, #GNUNET_SYSERR + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_value_yesno ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option); + + +/** + * Get Crockford32-encoded fixed-size binary data from a configuration. + * + * @param cfg configuration to access + * @param section section to access + * @param option option to access + * @param buf where to store the decoded binary result + * @param buf_size exact number of bytes to store in @a buf + * @return #GNUNET_OK on success + * #GNUNET_NO is the value does not exist + * #GNUNET_SYSERR on decoding error + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_get_data (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + void *buf, + size_t buf_size); + + +/** + * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" + * where either in the "PATHS" section or the environment "FOO" is + * set to "DIRECTORY". We also support default expansion, + * i.e. ${VARIABLE:-default} will expand to $VARIABLE if VARIABLE is + * set in PATHS or the environment, and otherwise to "default". Note + * that "default" itself can also be a $-expression, thus + * "${VAR1:-{$VAR2}}" will expand to VAR1 and if that is not defined + * to VAR2. + * + * @param cfg configuration to use for path expansion + * @param orig string to $-expand (will be freed!) Note that multiple + * $-expressions can be present in this string. They will all be + * $-expanded. + * @return $-expanded string + */ +char * +GNUNET_CONFIGURATION_expand_dollar ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + char *orig); + + +/** + * Set a configuration value that should be a number. + * + * @param cfg configuration to update + * @param section section of interest + * @param option option of interest + * @param number value to set + */ +void +GNUNET_CONFIGURATION_set_value_number (struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + unsigned long long number); + + +/** + * Set a configuration value that should be a string. + * + * @param cfg configuration to update + * @param section section of interest + * @param option option of interest + * @param value value to set + */ +void +GNUNET_CONFIGURATION_set_value_string ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + const char *value); + + +/** + * Remove a filename from a configuration value that + * represents a list of filenames + * + * @param cfg configuration to update + * @param section section of interest + * @param option option of interest + * @param value filename to remove + * @return #GNUNET_OK on success, + * #GNUNET_SYSERR if the filename is not in the list + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_remove_value_filename ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + const char *value); + + +/** + * Append a filename to a configuration value that + * represents a list of filenames + * + * @param cfg configuration to update + * @param section section of interest + * @param option option of interest + * @param value filename to append + * @return #GNUNET_OK on success, + * #GNUNET_SYSERR if the filename already in the list + */ +enum GNUNET_GenericReturnValue +GNUNET_CONFIGURATION_append_value_filename ( + struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + const char *option, + const char *value); + + +/** + * Closure for #GNUNET_CONFIGURATION_config_tool_run() + * with settings for what should be done with the + * configuration. + */ +struct GNUNET_CONFIGURATION_ConfigSettings +{ + + /** + * Must be set to the API version, i.e. #GNUNET_UTIL_VERSION. Used to + * detect which version of the struct the client is using. + */ + unsigned int api_version; + + /** + * Name of the section + */ + char *section; + + /** + * Name of the option + */ + char *option; + + /** + * Value to set + */ + char *value; + + /** + * Treat option as a filename. + */ + int is_filename; + + /** + * Whether to show the sections. + */ + int list_sections; + + /** + * Should we write out the configuration file, even if no value was changed? + */ + int rewrite; + + /** + * Should we give extra diagnostics? + */ + int diagnostics; + + /** + * Should the generated configuration file contain the whole configuration? + */ + int full; + + /** + * Return value from the operation, to be returned + * from 'main'. + */ + int global_ret; + +}; + + +/** + * Macro that expands to a set of GNUNET-getopt directives + * to initialize a `struct GNUNET_CONFIGURATION_ConfigSettings` + * from the command line. + * + * @param cs configuration settings to initialize + */ +#define GNUNET_CONFIGURATION_CONFIG_OPTIONS(cs) \ + GNUNET_GETOPT_option_flag ( \ + 'F', \ + "full", \ + gettext_noop ( \ + "write the full configuration file, including default values"), \ + &(cs)->full), \ + GNUNET_GETOPT_option_flag ( \ + 'f', \ + "filename", \ + gettext_noop ( \ + "interpret option value as a filename (with $-expansion)"), \ + &(cs)->is_filename), \ + GNUNET_GETOPT_option_string ('o', \ + "option", \ + "OPTION", \ + gettext_noop ( \ + "name of the option to access"), \ + &(cs)->option), \ + GNUNET_GETOPT_option_flag ( \ + 'r', \ + "rewrite", \ + gettext_noop ( \ + "rewrite the configuration file, even if nothing changed"), \ + &(cs)->rewrite), \ + GNUNET_GETOPT_option_flag ( \ + 'd', \ + "diagnostics", \ + gettext_noop ( \ + "output extra diagnostics"), \ + &(cs)->diagnostics), \ + GNUNET_GETOPT_option_flag ('S', \ + "list-sections", \ + gettext_noop ( \ + "print available configuration sections"), \ + &(cs)->list_sections), \ + GNUNET_GETOPT_option_string ('s', \ + "section", \ + "SECTION", \ + gettext_noop ( \ + "name of the section to access"), \ + &(cs)->section), \ + GNUNET_GETOPT_option_string ('V', \ + "value", \ + "VALUE", \ + gettext_noop ("value to set"), \ + &(cs)->value) + + +/** + * Free resources associated with @a cs. + * + * @param[in] cs settings to free (actual memory + * of @a cs itself is not released) + */ +void +GNUNET_CONFIGURATION_config_settings_free ( + struct GNUNET_CONFIGURATION_ConfigSettings *cs); + + +/** + * Main task to run to perform operations typical for + * gnunet-config as per the configuration settings + * given in @a cls. + * + * @param cls closure with the `struct GNUNET_CONFIGURATION_ConfigSettings` + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, + * can be NULL!) + * @param cfg configuration + */ +void +GNUNET_CONFIGURATION_config_tool_run ( + void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ /* end of group configuration */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_container_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_container_lib.h @@ -0,0 +1,2354 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-2015 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 + * @author Nils Durner + * + * @file + * Container classes for GNUnet + * + * @addtogroup container + * Common data structures in GNUnet programs + * @{ + * + * @defgroup hashmap MultiHashMap + * Hash map with multiple values per key. + * + * @see [Documentation](https://gnunet.org/util_multihashmap) + * + * @defgroup heap Heap + * Min- or max-heap with arbitrary element removal + * + * @defgroup bloomfilter Bloom filter + * Probabilistic set tests + * + * @defgroup dll Doubly-linked list + * + * @see [Documentation](https://gnunet.org/mdll-api) + * + * + * @} + */ + +#include "gnunet_common.h" +#if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_CONTAINER_LIB_H +#define GNUNET_CONTAINER_LIB_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/* add error and config prototypes */ + +#include "gnunet_crypto_lib.h" + + +/** + * Try to compress the given block of data using libz. Only returns + * the compressed block if compression worked and the new block is + * actually smaller. Decompress using #GNUNET_decompress(). + * + * @param data block to compress; if compression + * resulted in a smaller block, the first + * bytes of data are updated to the compressed + * data + * @param old_size number of bytes in data + * @param[out] result set to the compressed data, if compression worked + * @param[out] new_size set to size of result, if compression worked + * @return #GNUNET_YES if compression reduce the size, + * #GNUNET_NO if compression did not help + */ +int +GNUNET_try_compression (const char *data, + size_t old_size, + char **result, + size_t *new_size); + + +/** + * Decompress input, return the decompressed data as output. Dual to + * #GNUNET_try_compression(). Caller must set @a output_size to the + * number of bytes that were originally compressed. + * + * @param input compressed data + * @param input_size number of bytes in input + * @param output_size expected size of the output + * @return NULL on error, buffer of @a output_size decompressed bytes otherwise + */ +char * +GNUNET_decompress (const char *input, size_t input_size, size_t output_size); + + +/* ******************* bloomfilter ***************** */ + +/** + * @brief bloomfilter representation (opaque) + * @ingroup bloomfilter + */ +struct GNUNET_CONTAINER_BloomFilter; + + +/** + * @ingroup bloomfilter + * Iterator over `struct GNUNET_HashCode`. + * + * @param cls closure + * @param next set to the next hash code + * @return #GNUNET_YES if next was updated + * #GNUNET_NO if there are no more entries + */ +typedef int (*GNUNET_CONTAINER_HashCodeIterator) (void *cls, + struct GNUNET_HashCode *next); + + +/** + * @ingroup bloomfilter + * Load a Bloom filter from a file. + * + * @param filename the name of the file (or the prefix) + * @param size the size of the bloom-filter (number of + * bytes of storage space to use); will be rounded up + * to next power of 2 + * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per + * element (number of bits set per element in the set) + * @return the bloomfilter + */ +struct GNUNET_CONTAINER_BloomFilter * +GNUNET_CONTAINER_bloomfilter_load (const char *filename, + size_t size, + unsigned int k); + + +/** + * @ingroup bloomfilter + * Create a Bloom filter from raw bits. + * + * @param data the raw bits in memory (maybe NULL, + * in which case all bits should be considered + * to be zero). + * @param size the size of the bloom-filter (number of + * bytes of storage space to use); also size of @a data + * -- unless data is NULL. Must be a power of 2. + * @param k the number of #GNUNET_CRYPTO_hash-functions to apply per + * element (number of bits set per element in the set) + * @return the bloomfilter + */ +struct GNUNET_CONTAINER_BloomFilter * +GNUNET_CONTAINER_bloomfilter_init (const char *data, + size_t size, + unsigned int k); + + +/** + * @ingroup bloomfilter + * Copy the raw data of this Bloom filter into + * the given data array. + * + * @param data where to write the data + * @param size the size of the given @a data array + * @return #GNUNET_SYSERR if the data array of the wrong size + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_bloomfilter_get_raw_data ( + const struct GNUNET_CONTAINER_BloomFilter *bf, + char *data, + size_t size); + + +/** + * @ingroup bloomfilter + * Test if an element is in the filter. + * + * @param e the element + * @param bf the filter + * @return true if the element is in the filter, false if not + */ +bool +GNUNET_CONTAINER_bloomfilter_test ( + const struct GNUNET_CONTAINER_BloomFilter *bf, + const struct GNUNET_HashCode *e); + + +/** + * @ingroup bloomfilter + * Add an element to the filter. + * + * @param bf the filter + * @param e the element + */ +void +GNUNET_CONTAINER_bloomfilter_add (struct GNUNET_CONTAINER_BloomFilter *bf, + const struct GNUNET_HashCode *e); + + +/** + * @ingroup bloomfilter + * Remove an element from the filter. + * + * @param bf the filter + * @param e the element to remove + */ +void +GNUNET_CONTAINER_bloomfilter_remove (struct GNUNET_CONTAINER_BloomFilter *bf, + const struct GNUNET_HashCode *e); + + +/** + * @ingroup bloomfilter + * Create a copy of a bloomfilter. + * + * @param bf the filter + * @return copy of bf + */ +struct GNUNET_CONTAINER_BloomFilter * +GNUNET_CONTAINER_bloomfilter_copy ( + const struct GNUNET_CONTAINER_BloomFilter *bf); + + +/** + * @ingroup bloomfilter + * Free the space associated with a filter + * in memory, flush to drive if needed (do not + * free the space on the drive). + * + * @param bf the filter + */ +void +GNUNET_CONTAINER_bloomfilter_free (struct GNUNET_CONTAINER_BloomFilter *bf); + + +/** + * Get the number of the addresses set per element in the bloom filter. + * + * @param bf the filter + * @return addresses set per element in the bf + */ +size_t +GNUNET_CONTAINER_bloomfilter_get_element_addresses ( + const struct GNUNET_CONTAINER_BloomFilter *bf); + + +/** + * @ingroup bloomfilter + * Get size of the bloom filter. + * + * @param bf the filter + * @return number of bytes used for the data of the bloom filter + */ +size_t +GNUNET_CONTAINER_bloomfilter_get_size ( + const struct GNUNET_CONTAINER_BloomFilter *bf); + + +/** + * @ingroup bloomfilter + * Reset a Bloom filter to empty. + * + * @param bf the filter + */ +void +GNUNET_CONTAINER_bloomfilter_clear (struct GNUNET_CONTAINER_BloomFilter *bf); + + +/** + * @ingroup bloomfilter + * "or" the entries of the given raw data array with the + * data of the given Bloom filter. Assumes that + * the @a size of the @a data array and the current filter + * match. + * + * @param bf the filter + * @param data data to OR-in + * @param size size of @a data + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_bloomfilter_or (struct GNUNET_CONTAINER_BloomFilter *bf, + const char *data, + size_t size); + + +/** + * @ingroup bloomfilter + * "or" the entries of the given raw data array with the + * data of the given Bloom filter. Assumes that + * the size of the two filters matches. + * + * @param bf the filter + * @param to_or the bloomfilter to or-in + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_bloomfilter_or2 ( + struct GNUNET_CONTAINER_BloomFilter *bf, + const struct GNUNET_CONTAINER_BloomFilter *to_or); + + +/** + * @ingroup bloomfilter + * Resize a bloom filter. Note that this operation + * is pretty costly. Essentially, the Bloom filter + * needs to be completely re-build. + * + * @param bf the filter + * @param iterator an iterator over all elements stored in the BF + * @param iterator_cls closure for @a iterator + * @param size the new size for the filter + * @param k the new number of #GNUNET_CRYPTO_hash-function to apply per element + */ +void +GNUNET_CONTAINER_bloomfilter_resize (struct GNUNET_CONTAINER_BloomFilter *bf, + GNUNET_CONTAINER_HashCodeIterator iterator, + void *iterator_cls, + size_t size, + unsigned int k); + + + +/* ******************************* HashMap **************************** */ + +/** + * @ingroup hashmap + * Opaque handle for a HashMap. + */ +struct GNUNET_CONTAINER_MultiHashMap; + +/** + * @ingroup hashmap + * Opaque handle to an iterator over + * a multihashmap. + */ +struct GNUNET_CONTAINER_MultiHashMapIterator; + +/** + * @ingroup hashmap + * Options for storing values in the HashMap. + */ +enum GNUNET_CONTAINER_MultiHashMapOption +{ + /** + * @ingroup hashmap + * If a value with the given key exists, replace it. Note that the + * old value would NOT be freed by replace (the application has to + * make sure that this happens if required). + */ + GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE, + + /** + * @ingroup hashmap + * Allow multiple values with the same key. + */ + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, + + /** + * @ingroup hashmap + * There must only be one value per key; storing a value should fail + * if a value under the same key already exists. + */ + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, + + /** + * @ingroup hashmap There must only be one value per key, but don't + * bother checking if a value already exists (faster than + * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY; implemented + * just like #GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE but this + * option documents better what is intended if + * #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY is what is + * desired). + */ + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST +}; + + +/** + * @ingroup hashmap + * Iterator over hash map entries. + * + * @param cls closure + * @param key current key code + * @param value value in the hash map + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_CONTAINER_MultiHashMapIteratorCallback)( + void *cls, + const struct GNUNET_HashCode *key, + void *value); + + +/** + * @ingroup hashmap + * Create a multi hash map. + * + * @param len initial size (map will grow as needed) + * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default; + * #GNUNET_YES means that on 'put', the 'key' does not have + * to be copied as the destination of the pointer is + * guaranteed to be life as long as the value is stored in + * the hashmap. This can significantly reduce memory + * consumption, but of course is also a recipe for + * heap corruption if the assumption is not true. Only + * use this if (1) memory use is important in this case and + * (2) you have triple-checked that the invariant holds + * @return NULL on error + */ +struct GNUNET_CONTAINER_MultiHashMap * +GNUNET_CONTAINER_multihashmap_create (unsigned int len, + int do_not_copy_keys); + + +/** + * @ingroup hashmap + * Destroy a hash map. Will not free any values + * stored in the hash map! + * + * @param map the map + */ +void +GNUNET_CONTAINER_multihashmap_destroy (struct + GNUNET_CONTAINER_MultiHashMap *map); + + +/** + * @ingroup hashmap + * Given a key find a value in the map matching the key. + * + * @param map the map + * @param key what to look for + * @return NULL if no value was found; note that + * this is indistinguishable from values that just + * happen to be NULL; use "contains" to test for + * key-value pairs with value NULL + */ +void * +GNUNET_CONTAINER_multihashmap_get ( + const struct GNUNET_CONTAINER_MultiHashMap *map, + const struct GNUNET_HashCode *key); + + +/** + * @ingroup hashmap + * Remove the given key-value pair from the map. Note that if the + * key-value pair is in the map multiple times, only one of the pairs + * will be removed. + * + * @param map the map + * @param key key of the key-value pair + * @param value value of the key-value pair + * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair + * is not in the map + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map, + const struct GNUNET_HashCode *key, + const void *value); + +/** + * @ingroup hashmap + * Remove all entries for the given key from the map. + * Note that the values would not be "freed". + * + * @param map the map + * @param key identifies values to be removed + * @return number of values removed + */ +int +GNUNET_CONTAINER_multihashmap_remove_all ( + struct GNUNET_CONTAINER_MultiHashMap *map, + const struct GNUNET_HashCode *key); + + +/** + * @ingroup hashmap + * Remove all entries from the map. + * Note that the values would not be "freed". + * + * @param map the map + * @return number of values removed + */ +unsigned int +GNUNET_CONTAINER_multihashmap_clear (struct GNUNET_CONTAINER_MultiHashMap *map); + + +/** + * @ingroup hashmap + * Check if the map contains any value under the given + * key (including values that are NULL). + * + * @param map the map + * @param key the key to test if a value exists for it + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap_contains ( + const struct GNUNET_CONTAINER_MultiHashMap *map, + const struct GNUNET_HashCode *key); + + +/** + * @ingroup hashmap + * Check if the map contains the given value under the given + * key. + * + * @param map the map + * @param key the key to test if a value exists for it + * @param value value to test for + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap_contains_value ( + const struct GNUNET_CONTAINER_MultiHashMap *map, + const struct GNUNET_HashCode *key, + const void *value); + + +/** + * @ingroup hashmap + * Store a key-value pair in the map. + * + * @param map the map + * @param key key to use + * @param value value to use + * @param opt options for put + * @return #GNUNET_OK on success, + * #GNUNET_NO if a value was replaced (with REPLACE) + * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the + * value already exists + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap_put ( + struct GNUNET_CONTAINER_MultiHashMap *map, + const struct GNUNET_HashCode *key, + void *value, + enum GNUNET_CONTAINER_MultiHashMapOption opt); + +/** + * @ingroup hashmap + * Get the number of key-value pairs in the map. + * + * @param map the map + * @return the number of key value pairs + */ +unsigned int +GNUNET_CONTAINER_multihashmap_size ( + const struct GNUNET_CONTAINER_MultiHashMap *map); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map. + * + * @param map the map + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multihashmap_iterate ( + struct GNUNET_CONTAINER_MultiHashMap *map, + GNUNET_CONTAINER_MultiHashMapIteratorCallback it, + void *it_cls); + + +/** + * @ingroup hashmap + * Create an iterator for a multihashmap. + * The iterator can be used to retrieve all the elements in the multihashmap + * one by one, without having to handle all elements at once (in contrast to + * #GNUNET_CONTAINER_multihashmap_iterate). Note that the iterator can not be + * used anymore if elements have been removed from 'map' after the creation of + * the iterator, or 'map' has been destroyed. Adding elements to 'map' may + * result in skipped or repeated elements. + * + * @param map the map to create an iterator for + * @return an iterator over the given multihashmap @a map + */ +struct GNUNET_CONTAINER_MultiHashMapIterator * +GNUNET_CONTAINER_multihashmap_iterator_create ( + const struct GNUNET_CONTAINER_MultiHashMap *map); + + +/** + * @ingroup hashmap + * Retrieve the next element from the hash map at the iterator's + * position. If there are no elements left, #GNUNET_NO is returned, + * and @a key and @a value are not modified. This operation is only + * allowed if no elements have been removed from the multihashmap + * since the creation of @a iter, and the map has not been destroyed. + * Adding elements may result in repeating or skipping elements. + * + * @param iter the iterator to get the next element from + * @param key pointer to store the key in, can be NULL + * @param value pointer to store the value in, can be NULL + * @return #GNUNET_YES we returned an element, + * #GNUNET_NO if we are out of elements + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap_iterator_next ( + struct GNUNET_CONTAINER_MultiHashMapIterator *iter, + struct GNUNET_HashCode *key, + const void **value); + + +/** + * @ingroup hashmap + * Destroy a multihashmap iterator. + * + * @param iter the iterator to destroy + */ +void +GNUNET_CONTAINER_multihashmap_iterator_destroy ( + struct GNUNET_CONTAINER_MultiHashMapIterator *iter); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map that match a particular key. + * + * @param map the map + * @param key key that the entries must correspond to + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap_get_multiple ( + struct GNUNET_CONTAINER_MultiHashMap *map, + const struct GNUNET_HashCode *key, + GNUNET_CONTAINER_MultiHashMapIteratorCallback it, + void *it_cls); + + +/** + * @ingroup hashmap + * Call @a it on a random value from the map, or not at all + * if the map is empty. Note that this function has linear + * complexity (in the size of the map). + * + * @param map the map + * @param it function to call on a random entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, zero or one. + */ +unsigned int +GNUNET_CONTAINER_multihashmap_get_random ( + const struct GNUNET_CONTAINER_MultiHashMap *map, + GNUNET_CONTAINER_MultiHashMapIteratorCallback it, + void *it_cls); + + +/* ***************** Version of Multihashmap for peer identities ****************** */ + +/** + * @ingroup hashmap + * Iterator over hash map entries. + * + * @param cls closure + * @param key current public key + * @param value value in the hash map + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_CONTAINER_PeerMapIterator)( + void *cls, + const struct GNUNET_PeerIdentity *key, + void *value); + + +/** + * Hash map from peer identities to values. + */ +struct GNUNET_CONTAINER_MultiPeerMap; + + +/** + * @ingroup hashmap + * Create a multi peer map (hash map for public keys of peers). + * + * @param len initial size (map will grow as needed) + * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default; + * #GNUNET_YES means that on 'put', the 'key' does not have + * to be copied as the destination of the pointer is + * guaranteed to be life as long as the value is stored in + * the hashmap. This can significantly reduce memory + * consumption, but of course is also a recipe for + * heap corruption if the assumption is not true. Only + * use this if (1) memory use is important in this case and + * (2) you have triple-checked that the invariant holds + * @return NULL on error + */ +struct GNUNET_CONTAINER_MultiPeerMap * +GNUNET_CONTAINER_multipeermap_create (unsigned int len, int do_not_copy_keys); + + +/** + * @ingroup hashmap + * Destroy a hash map. Will not free any values + * stored in the hash map! + * + * @param map the map + */ +void +GNUNET_CONTAINER_multipeermap_destroy ( + struct GNUNET_CONTAINER_MultiPeerMap *map); + + +/** + * @ingroup hashmap + * Given a key find a value in the map matching the key. + * + * @param map the map + * @param key what to look for + * @return NULL if no value was found; note that + * this is indistinguishable from values that just + * happen to be NULL; use "contains" to test for + * key-value pairs with value NULL + */ +void * +GNUNET_CONTAINER_multipeermap_get ( + const struct GNUNET_CONTAINER_MultiPeerMap *map, + const struct GNUNET_PeerIdentity *key); + + +/** + * @ingroup hashmap + * Remove the given key-value pair from the map. Note that if the + * key-value pair is in the map multiple times, only one of the pairs + * will be removed. + * + * @param map the map + * @param key key of the key-value pair + * @param value value of the key-value pair + * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair + * is not in the map + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map, + const struct GNUNET_PeerIdentity *key, + const void *value); + +/** + * @ingroup hashmap + * Remove all entries for the given key from the map. + * Note that the values would not be "freed". + * + * @param map the map + * @param key identifies values to be removed + * @return number of values removed + */ +int +GNUNET_CONTAINER_multipeermap_remove_all ( + struct GNUNET_CONTAINER_MultiPeerMap *map, + const struct GNUNET_PeerIdentity *key); + + +/** + * @ingroup hashmap + * Check if the map contains any value under the given + * key (including values that are NULL). + * + * @param map the map + * @param key the key to test if a value exists for it + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multipeermap_contains ( + const struct GNUNET_CONTAINER_MultiPeerMap *map, + const struct GNUNET_PeerIdentity *key); + + +/** + * @ingroup hashmap + * Check if the map contains the given value under the given + * key. + * + * @param map the map + * @param key the key to test if a value exists for it + * @param value value to test for + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multipeermap_contains_value ( + const struct GNUNET_CONTAINER_MultiPeerMap *map, + const struct GNUNET_PeerIdentity *key, + const void *value); + + +/** + * @ingroup hashmap + * Store a key-value pair in the map. + * + * @param map the map + * @param key key to use + * @param value value to use + * @param opt options for put + * @return #GNUNET_OK on success, + * #GNUNET_NO if a value was replaced (with REPLACE) + * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the + * value already exists + */ +int +GNUNET_CONTAINER_multipeermap_put ( + struct GNUNET_CONTAINER_MultiPeerMap *map, + const struct GNUNET_PeerIdentity *key, + void *value, + enum GNUNET_CONTAINER_MultiHashMapOption opt); + + +/** + * @ingroup hashmap + * Get the number of key-value pairs in the map. + * + * @param map the map + * @return the number of key value pairs + */ +unsigned int +GNUNET_CONTAINER_multipeermap_size ( + const struct GNUNET_CONTAINER_MultiPeerMap *map); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map. + * + * @param map the map + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multipeermap_iterate ( + struct GNUNET_CONTAINER_MultiPeerMap *map, + GNUNET_CONTAINER_PeerMapIterator it, + void *it_cls); + + +struct GNUNET_CONTAINER_MultiPeerMapIterator; +/** + * @ingroup hashmap + * Create an iterator for a multihashmap. + * The iterator can be used to retrieve all the elements in the multihashmap + * one by one, without having to handle all elements at once (in contrast to + * #GNUNET_CONTAINER_multipeermap_iterate). Note that the iterator can not be + * used anymore if elements have been removed from @a map after the creation of + * the iterator, or 'map' has been destroyed. Adding elements to @a map may + * result in skipped or repeated elements. + * + * @param map the map to create an iterator for + * @return an iterator over the given multihashmap @a map + */ +struct GNUNET_CONTAINER_MultiPeerMapIterator * +GNUNET_CONTAINER_multipeermap_iterator_create ( + const struct GNUNET_CONTAINER_MultiPeerMap *map); + + +/** + * @ingroup hashmap + * Retrieve the next element from the hash map at the iterator's + * position. If there are no elements left, #GNUNET_NO is returned, + * and @a key and @a value are not modified. + * + * This operation is only allowed if no elements have been removed + * from the multihashmap since the creation of @a iter, and the map + * has not been destroyed. + * + * Adding elements may result in repeating or skipping elements. + * + * @param iter the iterator to get the next element from + * @param key pointer to store the key in, can be NULL + * @param value pointer to store the value in, can be NULL + * @return #GNUNET_YES we returned an element, + * #GNUNET_NO if we are out of elements + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multipeermap_iterator_next ( + struct GNUNET_CONTAINER_MultiPeerMapIterator *iter, + struct GNUNET_PeerIdentity *key, + const void **value); + + +/** + * @ingroup hashmap + * Destroy a multipeermap iterator. + * + * @param iter the iterator to destroy + */ +void +GNUNET_CONTAINER_multipeermap_iterator_destroy ( + struct GNUNET_CONTAINER_MultiPeerMapIterator *iter); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map that match a particular key. + * + * @param map the map + * @param key public key that the entries must correspond to + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multipeermap_get_multiple ( + struct GNUNET_CONTAINER_MultiPeerMap *map, + const struct GNUNET_PeerIdentity *key, + GNUNET_CONTAINER_PeerMapIterator it, + void *it_cls); + + +/** + * @ingroup hashmap + * Call @a it on a random value from the map, or not at all + * if the map is empty. Note that this function has linear + * complexity (in the size of the map). + * + * @param map the map + * @param it function to call on a random entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, zero or one. + */ +unsigned int +GNUNET_CONTAINER_multipeermap_get_random ( + const struct GNUNET_CONTAINER_MultiPeerMap *map, + GNUNET_CONTAINER_PeerMapIterator it, + void *it_cls); + + +/* ***************** Version of Multihashmap for short hashes ****************** */ + +/** + * @ingroup hashmap + * Iterator over hash map entries. + * + * @param cls closure + * @param key current public key + * @param value value in the hash map + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_CONTAINER_ShortmapIterator)( + void *cls, + const struct GNUNET_ShortHashCode *key, + void *value); + + +/** + * Hash map from peer identities to values. + */ +struct GNUNET_CONTAINER_MultiShortmap; + + +/** + * @ingroup hashmap + * Create a multi peer map (hash map for public keys of peers). + * + * @param len initial size (map will grow as needed) + * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default; + * #GNUNET_YES means that on 'put', the 'key' does not have + * to be copied as the destination of the pointer is + * guaranteed to be life as long as the value is stored in + * the hashmap. This can significantly reduce memory + * consumption, but of course is also a recipe for + * heap corruption if the assumption is not true. Only + * use this if (1) memory use is important in this case and + * (2) you have triple-checked that the invariant holds + * @return NULL on error + */ +struct GNUNET_CONTAINER_MultiShortmap * +GNUNET_CONTAINER_multishortmap_create (unsigned int len, int do_not_copy_keys); + + +/** + * @ingroup hashmap + * Destroy a hash map. Will not free any values + * stored in the hash map! + * + * @param map the map + */ +void +GNUNET_CONTAINER_multishortmap_destroy ( + struct GNUNET_CONTAINER_MultiShortmap *map); + + +/** + * @ingroup hashmap + * Given a key find a value in the map matching the key. + * + * @param map the map + * @param key what to look for + * @return NULL if no value was found; note that + * this is indistinguishable from values that just + * happen to be NULL; use "contains" to test for + * key-value pairs with value NULL + */ +void * +GNUNET_CONTAINER_multishortmap_get ( + const struct GNUNET_CONTAINER_MultiShortmap *map, + const struct GNUNET_ShortHashCode *key); + + +/** + * @ingroup hashmap + * Remove the given key-value pair from the map. Note that if the + * key-value pair is in the map multiple times, only one of the pairs + * will be removed. + * + * @param map the map + * @param key key of the key-value pair + * @param value value of the key-value pair + * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair + * is not in the map + */ +int +GNUNET_CONTAINER_multishortmap_remove ( + struct GNUNET_CONTAINER_MultiShortmap *map, + const struct GNUNET_ShortHashCode *key, + const void *value); + +/** + * @ingroup hashmap + * Remove all entries for the given key from the map. + * Note that the values would not be "freed". + * + * @param map the map + * @param key identifies values to be removed + * @return number of values removed + */ +int +GNUNET_CONTAINER_multishortmap_remove_all ( + struct GNUNET_CONTAINER_MultiShortmap *map, + const struct GNUNET_ShortHashCode *key); + + +/** + * @ingroup hashmap + * Check if the map contains any value under the given + * key (including values that are NULL). + * + * @param map the map + * @param key the key to test if a value exists for it + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +int +GNUNET_CONTAINER_multishortmap_contains ( + const struct GNUNET_CONTAINER_MultiShortmap *map, + const struct GNUNET_ShortHashCode *key); + + +/** + * @ingroup hashmap + * Check if the map contains the given value under the given + * key. + * + * @param map the map + * @param key the key to test if a value exists for it + * @param value value to test for + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +int +GNUNET_CONTAINER_multishortmap_contains_value ( + const struct GNUNET_CONTAINER_MultiShortmap *map, + const struct GNUNET_ShortHashCode *key, + const void *value); + + +/** + * @ingroup hashmap + * Store a key-value pair in the map. + * + * @param map the map + * @param key key to use + * @param value value to use + * @param opt options for put + * @return #GNUNET_OK on success, + * #GNUNET_NO if a value was replaced (with REPLACE) + * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the + * value already exists + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multishortmap_put ( + struct GNUNET_CONTAINER_MultiShortmap *map, + const struct GNUNET_ShortHashCode *key, + void *value, + enum GNUNET_CONTAINER_MultiHashMapOption opt); + + +/** + * @ingroup hashmap + * Get the number of key-value pairs in the map. + * + * @param map the map + * @return the number of key value pairs + */ +unsigned int +GNUNET_CONTAINER_multishortmap_size ( + const struct GNUNET_CONTAINER_MultiShortmap *map); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map. + * + * @param map the map + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multishortmap_iterate ( + struct GNUNET_CONTAINER_MultiShortmap *map, + GNUNET_CONTAINER_ShortmapIterator it, + void *it_cls); + + +struct GNUNET_CONTAINER_MultiShortmapIterator; + + +/** + * @ingroup hashmap + * Create an iterator for a multihashmap. + * The iterator can be used to retrieve all the elements in the multihashmap + * one by one, without having to handle all elements at once (in contrast to + * #GNUNET_CONTAINER_multishortmap_iterate). Note that the iterator can not be + * used anymore if elements have been removed from @a map after the creation of + * the iterator, or 'map' has been destroyed. Adding elements to @a map may + * result in skipped or repeated elements. + * + * @param map the map to create an iterator for + * @return an iterator over the given multihashmap @a map + */ +struct GNUNET_CONTAINER_MultiShortmapIterator * +GNUNET_CONTAINER_multishortmap_iterator_create ( + const struct GNUNET_CONTAINER_MultiShortmap *map); + + +/** + * @ingroup hashmap + * Retrieve the next element from the hash map at the iterator's + * position. If there are no elements left, #GNUNET_NO is returned, + * and @a key and @a value are not modified. This operation is only + * allowed if no elements have been removed from the multihashmap + * since the creation of @a iter, and the map has not been destroyed. + * Adding elements may result in repeating or skipping elements. + * + * @param iter the iterator to get the next element from + * @param key pointer to store the key in, can be NULL + * @param value pointer to store the value in, can be NULL + * @return #GNUNET_YES we returned an element, + * #GNUNET_NO if we are out of elements + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multishortmap_iterator_next ( + struct GNUNET_CONTAINER_MultiShortmapIterator *iter, + struct GNUNET_ShortHashCode *key, + const void **value); + + +/** + * @ingroup hashmap + * Destroy a multishortmap iterator. + * + * @param iter the iterator to destroy + */ +void +GNUNET_CONTAINER_multishortmap_iterator_destroy ( + struct GNUNET_CONTAINER_MultiShortmapIterator *iter); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map that match a particular key. + * + * @param map the map + * @param key public key that the entries must correspond to + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multishortmap_get_multiple ( + struct GNUNET_CONTAINER_MultiShortmap *map, + const struct GNUNET_ShortHashCode *key, + GNUNET_CONTAINER_ShortmapIterator it, + void *it_cls); + + +/** + * @ingroup hashmap + * Call @a it on a random value from the map, or not at all + * if the map is empty. Note that this function has linear + * complexity (in the size of the map). + * + * @param map the map + * @param it function to call on a random entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, zero or one. + */ +unsigned int +GNUNET_CONTAINER_multishortmap_get_random ( + const struct GNUNET_CONTAINER_MultiShortmap *map, + GNUNET_CONTAINER_ShortmapIterator it, + void *it_cls); + + +/* ***************** Version of Multihashmap for UUIDs ****************** */ + + +/** + * @ingroup hashmap + * Iterator over uuid map entries. + * + * @param cls closure + * @param key current public key + * @param value value in the hash map + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_CONTAINER_MultiUuidmapIteratorCallback)( + void *cls, + const struct GNUNET_Uuid *key, + void *value); + + +/** + * Hash map from peer identities to values. + */ +struct GNUNET_CONTAINER_MultiUuidmap; + + +/** + * @ingroup hashmap + * Create a multi peer map (hash map for public keys of peers). + * + * @param len initial size (map will grow as needed) + * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default; + * #GNUNET_YES means that on 'put', the 'key' does not have + * to be copied as the destination of the pointer is + * guaranteed to be life as long as the value is stored in + * the hashmap. This can significantly reduce memory + * consumption, but of course is also a recipe for + * heap corruption if the assumption is not true. Only + * use this if (1) memory use is important in this case and + * (2) you have triple-checked that the invariant holds + * @return NULL on error + */ +struct GNUNET_CONTAINER_MultiUuidmap * +GNUNET_CONTAINER_multiuuidmap_create (unsigned int len, int do_not_copy_keys); + + +/** + * @ingroup hashmap + * Destroy a hash map. Will not free any values + * stored in the hash map! + * + * @param map the map + */ +void +GNUNET_CONTAINER_multiuuidmap_destroy ( + struct GNUNET_CONTAINER_MultiUuidmap *map); + + +/** + * @ingroup hashmap + * Given a key find a value in the map matching the key. + * + * @param map the map + * @param key what to look for + * @return NULL if no value was found; note that + * this is indistinguishable from values that just + * happen to be NULL; use "contains" to test for + * key-value pairs with value NULL + */ +void * +GNUNET_CONTAINER_multiuuidmap_get ( + const struct GNUNET_CONTAINER_MultiUuidmap *map, + const struct GNUNET_Uuid *key); + + +/** + * @ingroup hashmap + * Remove the given key-value pair from the map. Note that if the + * key-value pair is in the map multiple times, only one of the pairs + * will be removed. + * + * @param map the map + * @param key key of the key-value pair + * @param value value of the key-value pair + * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair + * is not in the map + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multiuuidmap_remove (struct GNUNET_CONTAINER_MultiUuidmap *map, + const struct GNUNET_Uuid *key, + const void *value); + +/** + * @ingroup hashmap + * Remove all entries for the given key from the map. + * Note that the values would not be "freed". + * + * @param map the map + * @param key identifies values to be removed + * @return number of values removed + */ +int +GNUNET_CONTAINER_multiuuidmap_remove_all ( + struct GNUNET_CONTAINER_MultiUuidmap *map, + const struct GNUNET_Uuid *key); + + +/** + * @ingroup hashmap + * Check if the map contains any value under the given + * key (including values that are NULL). + * + * @param map the map + * @param key the key to test if a value exists for it + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multiuuidmap_contains ( + const struct GNUNET_CONTAINER_MultiUuidmap *map, + const struct GNUNET_Uuid *key); + + +/** + * @ingroup hashmap + * Check if the map contains the given value under the given + * key. + * + * @param map the map + * @param key the key to test if a value exists for it + * @param value value to test for + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multiuuidmap_contains_value ( + const struct GNUNET_CONTAINER_MultiUuidmap *map, + const struct GNUNET_Uuid *key, + const void *value); + + +/** + * @ingroup hashmap + * Store a key-value pair in the map. + * + * @param map the map + * @param key key to use + * @param value value to use + * @param opt options for put + * @return #GNUNET_OK on success, + * #GNUNET_NO if a value was replaced (with REPLACE) + * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the + * value already exists + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multiuuidmap_put ( + struct GNUNET_CONTAINER_MultiUuidmap *map, + const struct GNUNET_Uuid *key, + void *value, + enum GNUNET_CONTAINER_MultiHashMapOption opt); + + +/** + * @ingroup hashmap + * Get the number of key-value pairs in the map. + * + * @param map the map + * @return the number of key value pairs + */ +unsigned int +GNUNET_CONTAINER_multiuuidmap_size ( + const struct GNUNET_CONTAINER_MultiUuidmap *map); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map. + * + * @param map the map + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multiuuidmap_iterate ( + struct GNUNET_CONTAINER_MultiUuidmap *map, + GNUNET_CONTAINER_MultiUuidmapIteratorCallback it, + void *it_cls); + + +struct GNUNET_CONTAINER_MultiUuidmapIterator; + + +/** + * @ingroup hashmap + * Create an iterator for a multihashmap. + * The iterator can be used to retrieve all the elements in the multihashmap + * one by one, without having to handle all elements at once (in contrast to + * #GNUNET_CONTAINER_multiuuidmap_iterate). Note that the iterator can not be + * used anymore if elements have been removed from @a map after the creation of + * the iterator, or 'map' has been destroyed. Adding elements to @a map may + * result in skipped or repeated elements. + * + * @param map the map to create an iterator for + * @return an iterator over the given multihashmap @a map + */ +struct GNUNET_CONTAINER_MultiUuidmapIterator * +GNUNET_CONTAINER_multiuuidmap_iterator_create ( + const struct GNUNET_CONTAINER_MultiUuidmap *map); + + +/** + * @ingroup hashmap + * Retrieve the next element from the hash map at the iterator's + * position. If there are no elements left, #GNUNET_NO is returned, + * and @a key and @a value are not modified. This operation is only + * allowed if no elements have been removed from the multihashmap + * since the creation of @a iter, and the map has not been destroyed. + * Adding elements may result in repeating or skipping elements. + * + * @param iter the iterator to get the next element from + * @param key pointer to store the key in, can be NULL + * @param value pointer to store the value in, can be NULL + * @return #GNUNET_YES we returned an element, + * #GNUNET_NO if we are out of elements + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multiuuidmap_iterator_next ( + struct GNUNET_CONTAINER_MultiUuidmapIterator *iter, + struct GNUNET_Uuid *key, + const void **value); + + +/** + * @ingroup hashmap + * Destroy a multiuuidmap iterator. + * + * @param iter the iterator to destroy + */ +void +GNUNET_CONTAINER_multiuuidmap_iterator_destroy ( + struct GNUNET_CONTAINER_MultiUuidmapIterator *iter); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map that match a particular key. + * + * @param map the map + * @param key public key that the entries must correspond to + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multiuuidmap_get_multiple ( + struct GNUNET_CONTAINER_MultiUuidmap *map, + const struct GNUNET_Uuid *key, + GNUNET_CONTAINER_MultiUuidmapIteratorCallback it, + void *it_cls); + + +/** + * @ingroup hashmap + * Call @a it on a random value from the map, or not at all + * if the map is empty. Note that this function has linear + * complexity (in the size of the map). + * + * @param map the map + * @param it function to call on a random entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, zero or one. + */ +unsigned int +GNUNET_CONTAINER_multiuuidmap_get_random ( + const struct GNUNET_CONTAINER_MultiUuidmap *map, + GNUNET_CONTAINER_MultiUuidmapIteratorCallback it, + void *it_cls); + + +/* Version of multihashmap with 32 bit keys */ + +/** + * @ingroup hashmap + * Opaque handle for the 32-bit key HashMap. + */ +struct GNUNET_CONTAINER_MultiHashMap32; + + +/** + * @ingroup hashmap + * Opaque handle to an iterator over + * a 32-bit key multihashmap. + */ +struct GNUNET_CONTAINER_MultiHashMap32Iterator; + + +/** + * @ingroup hashmap + * Iterator over hash map entries. + * + * @param cls closure + * @param key current key code + * @param value value in the hash map + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_CONTAINER_MultiHashMapIterator32Callback)( + void *cls, + uint32_t key, + void *value); + + +/** + * @ingroup hashmap + * Create a 32-bit key multi hash map. + * + * @param len initial size (map will grow as needed) + * @return NULL on error + */ +struct GNUNET_CONTAINER_MultiHashMap32 * +GNUNET_CONTAINER_multihashmap32_create (unsigned int len); + + +/** + * @ingroup hashmap + * Destroy a 32-bit key hash map. Will not free any values + * stored in the hash map! + * + * @param map the map + */ +void +GNUNET_CONTAINER_multihashmap32_destroy ( + struct GNUNET_CONTAINER_MultiHashMap32 *map); + + +/** + * @ingroup hashmap + * Get the number of key-value pairs in the map. + * + * @param map the map + * @return the number of key value pairs + */ +unsigned int +GNUNET_CONTAINER_multihashmap32_size ( + const struct GNUNET_CONTAINER_MultiHashMap32 *map); + + +/** + * @ingroup hashmap + * Given a key find a value in the map matching the key. + * + * @param map the map + * @param key what to look for + * @return NULL if no value was found; note that + * this is indistinguishable from values that just + * happen to be NULL; use "contains" to test for + * key-value pairs with value NULL + */ +void * +GNUNET_CONTAINER_multihashmap32_get ( + const struct GNUNET_CONTAINER_MultiHashMap32 *map, + uint32_t key); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map. + * + * @param map the map + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multihashmap32_iterate ( + struct GNUNET_CONTAINER_MultiHashMap32 *map, + GNUNET_CONTAINER_MultiHashMapIterator32Callback it, + void *it_cls); + + +/** + * @ingroup hashmap + * Remove the given key-value pair from the map. Note that if the + * key-value pair is in the map multiple times, only one of the pairs + * will be removed. + * + * @param map the map + * @param key key of the key-value pair + * @param value value of the key-value pair + * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair + * is not in the map + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap32_remove ( + struct GNUNET_CONTAINER_MultiHashMap32 *map, + uint32_t key, + const void *value); + + +/** + * @ingroup hashmap + * Remove all entries for the given key from the map. + * Note that the values would not be "freed". + * + * @param map the map + * @param key identifies values to be removed + * @return number of values removed + */ +int +GNUNET_CONTAINER_multihashmap32_remove_all ( + struct GNUNET_CONTAINER_MultiHashMap32 *map, + uint32_t key); + + +/** + * @ingroup hashmap + * Check if the map contains any value under the given + * key (including values that are NULL). + * + * @param map the map + * @param key the key to test if a value exists for it + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap32_contains ( + const struct GNUNET_CONTAINER_MultiHashMap32 *map, + uint32_t key); + + +/** + * @ingroup hashmap + * Check if the map contains the given value under the given + * key. + * + * @param map the map + * @param key the key to test if a value exists for it + * @param value value to test for + * @return #GNUNET_YES if such a value exists, + * #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap32_contains_value ( + const struct GNUNET_CONTAINER_MultiHashMap32 *map, + uint32_t key, + const void *value); + + +/** + * @ingroup hashmap + * Store a key-value pair in the map. + * + * @param map the map + * @param key key to use + * @param value value to use + * @param opt options for put + * @return #GNUNET_OK on success, + * #GNUNET_NO if a value was replaced (with REPLACE) + * #GNUNET_SYSERR if #GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY was the option and the + * value already exists + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap32_put ( + struct GNUNET_CONTAINER_MultiHashMap32 *map, + uint32_t key, + void *value, + enum GNUNET_CONTAINER_MultiHashMapOption opt); + + +/** + * @ingroup hashmap + * Iterate over all entries in the map that match a particular key. + * + * @param map the map + * @param key key that the entries must correspond to + * @param it function to call on each entry + * @param it_cls extra argument to @a it + * @return the number of key value pairs processed, + * #GNUNET_SYSERR if it aborted iteration + */ +int +GNUNET_CONTAINER_multihashmap32_get_multiple ( + struct GNUNET_CONTAINER_MultiHashMap32 *map, + uint32_t key, + GNUNET_CONTAINER_MultiHashMapIterator32Callback it, + void *it_cls); + + +/** + * Create an iterator for a 32-bit multihashmap. + * The iterator can be used to retrieve all the elements in the multihashmap + * one by one, without having to handle all elements at once (in contrast to + * #GNUNET_CONTAINER_multihashmap32_iterate). Note that the iterator can not be + * used anymore if elements have been removed from 'map' after the creation of + * the iterator, or 'map' has been destroyed. Adding elements to 'map' may + * result in skipped or repeated elements. + * + * @param map the map to create an iterator for + * @return an iterator over the given multihashmap map + */ +struct GNUNET_CONTAINER_MultiHashMap32Iterator * +GNUNET_CONTAINER_multihashmap32_iterator_create ( + const struct GNUNET_CONTAINER_MultiHashMap32 *map); + + +/** + * Retrieve the next element from the hash map at the iterator's position. + * If there are no elements left, GNUNET_NO is returned, and 'key' and 'value' + * are not modified. + * This operation is only allowed if no elements have been removed from the + * multihashmap since the creation of 'iter', and the map has not been destroyed. + * Adding elements may result in repeating or skipping elements. + * + * @param iter the iterator to get the next element from + * @param key pointer to store the key in, can be NULL + * @param value pointer to store the value in, can be NULL + * @return #GNUNET_YES we returned an element, + * #GNUNET_NO if we are out of elements + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_multihashmap32_iterator_next ( + struct GNUNET_CONTAINER_MultiHashMap32Iterator *iter, + uint32_t *key, + const void **value); + + +/** + * Destroy a 32-bit multihashmap iterator. + * + * @param iter the iterator to destroy + */ +void +GNUNET_CONTAINER_multihashmap32_iterator_destroy ( + struct GNUNET_CONTAINER_MultiHashMapIterator *iter); + + +/* ******************** doubly-linked list *************** */ +/* To avoid mistakes: head->prev == tail->next == NULL */ + +/** + * @ingroup dll + * Insert an element at the head of a DLL. Assumes that head, tail and + * element are structs with prev and next fields. + * + * @param head pointer to the head of the DLL + * @param tail pointer to the tail of the DLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_DLL_insert(head, tail, element) \ + do \ + { \ + GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \ + (element)->next = (head); \ + (element)->prev = NULL; \ + if ((tail) == NULL) \ + (tail) = element; \ + else \ + (head)->prev = element; \ + (head) = (element); \ + } while (0) + + +/** + * @ingroup dll + * Insert an element at the tail of a DLL. Assumes that head, tail and + * element are structs with prev and next fields. + * + * @param head pointer to the head of the DLL + * @param tail pointer to the tail of the DLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element) \ + do \ + { \ + GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \ + (element)->prev = (tail); \ + (element)->next = NULL; \ + if ((head) == NULL) \ + (head) = element; \ + else \ + (tail)->next = element; \ + (tail) = (element); \ + } while (0) + + +/** + * @ingroup dll + * Insert an element into a DLL after the given other element. Insert + * at the head if the other element is NULL. + * + * @param head pointer to the head of the DLL + * @param tail pointer to the tail of the DLL + * @param other prior element, NULL for insertion at head of DLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element) \ + do \ + { \ + GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \ + (element)->prev = (other); \ + if (NULL == other) \ + { \ + (element)->next = (head); \ + (head) = (element); \ + } \ + else \ + { \ + (element)->next = (other)->next; \ + (other)->next = (element); \ + } \ + if (NULL == (element)->next) \ + (tail) = (element); \ + else \ + (element)->next->prev = (element); \ + } while (0) + + +/** + * @ingroup dll + * Insert an element into a DLL before the given other element. Insert + * at the tail if the other element is NULL. + * + * @param head pointer to the head of the DLL + * @param tail pointer to the tail of the DLL + * @param other prior element, NULL for insertion at head of DLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_DLL_insert_before(head, tail, other, element) \ + do \ + { \ + GNUNET_assert (((element)->prev == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next == NULL) && ((tail) != (element))); \ + (element)->next = (other); \ + if (NULL == other) \ + { \ + (element)->prev = (tail); \ + (tail) = (element); \ + } \ + else \ + { \ + (element)->prev = (other)->prev; \ + (other)->prev = (element); \ + } \ + if (NULL == (element)->prev) \ + (head) = (element); \ + else \ + (element)->prev->next = (element); \ + } while (0) + + +/** + * @ingroup dll + * Remove an element from a DLL. Assumes that head, tail and + * element point to structs with prev and next fields. + * + * Using the head or tail pointer as the element + * argument does NOT work with this macro. + * Make sure to store head/tail in another pointer + * and use it to remove the head or tail of the list. + * + * @param head pointer to the head of the DLL + * @param tail pointer to the tail of the DLL + * @param element element to remove + */ +#define GNUNET_CONTAINER_DLL_remove(head, tail, element) \ + do \ + { \ + GNUNET_assert (((element)->prev != NULL) || ((head) == (element))); \ + GNUNET_assert (((element)->next != NULL) || ((tail) == (element))); \ + if ((element)->prev == NULL) \ + (head) = (element)->next; \ + else \ + (element)->prev->next = (element)->next; \ + if ((element)->next == NULL) \ + (tail) = (element)->prev; \ + else \ + (element)->next->prev = (element)->prev; \ + (element)->next = NULL; \ + (element)->prev = NULL; \ + } while (0) + + +/* ************ Multi-DLL interface, allows DLL elements to be + in multiple lists at the same time *********************** */ + +/** + * @ingroup dll + * Insert an element at the head of a MDLL. Assumes that head, tail and + * element are structs with prev and next fields. + * + * @param mdll suffix name for the next and prev pointers in the element + * @param head pointer to the head of the MDLL + * @param tail pointer to the tail of the MDLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_MDLL_insert(mdll, head, tail, element) \ + do \ + { \ + GNUNET_assert (((element)->prev_ ## mdll == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next_ ## mdll == NULL) && ((tail) != (element))); \ + (element)->next_ ## mdll = (head); \ + (element)->prev_ ## mdll = NULL; \ + if ((tail) == NULL) \ + (tail) = element; \ + else \ + (head)->prev_ ## mdll = element; \ + (head) = (element); \ + } while (0) + + +/** + * @ingroup dll + * Insert an element at the tail of a MDLL. Assumes that head, tail and + * element are structs with prev and next fields. + * + * @param mdll suffix name for the next and prev pointers in the element + * @param head pointer to the head of the MDLL + * @param tail pointer to the tail of the MDLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_MDLL_insert_tail(mdll, head, tail, element) \ + do \ + { \ + GNUNET_assert (((element)->prev_ ## mdll == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next_ ## mdll == NULL) && ((tail) != (element))); \ + (element)->prev_ ## mdll = (tail); \ + (element)->next_ ## mdll = NULL; \ + if ((head) == NULL) \ + (head) = element; \ + else \ + (tail)->next_ ## mdll = element; \ + (tail) = (element); \ + } while (0) + + +/** + * @ingroup dll + * Insert an element into a MDLL after the given other element. Insert + * at the head if the other element is NULL. + * + * @param mdll suffix name for the next and prev pointers in the element + * @param head pointer to the head of the MDLL + * @param tail pointer to the tail of the MDLL + * @param other prior element, NULL for insertion at head of MDLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_MDLL_insert_after(mdll, head, tail, other, element) \ + do \ + { \ + GNUNET_assert (((element)->prev_ ## mdll == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next_ ## mdll == NULL) && ((tail) != (element))); \ + (element)->prev_ ## mdll = (other); \ + if (NULL == other) \ + { \ + (element)->next_ ## mdll = (head); \ + (head) = (element); \ + } \ + else \ + { \ + (element)->next_ ## mdll = (other)->next_ ## mdll; \ + (other)->next_ ## mdll = (element); \ + } \ + if (NULL == (element)->next_ ## mdll) \ + (tail) = (element); \ + else \ + (element)->next_ ## mdll->prev_ ## mdll = (element); \ + } while (0) + + +/** + * @ingroup dll + * Insert an element into a MDLL before the given other element. Insert + * at the tail if the other element is NULL. + * + * @param mdll suffix name for the next and prev pointers in the element + * @param head pointer to the head of the MDLL + * @param tail pointer to the tail of the MDLL + * @param other prior element, NULL for insertion at head of MDLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_MDLL_insert_before(mdll, head, tail, other, element) \ + do \ + { \ + GNUNET_assert (((element)->prev_ ## mdll == NULL) && ((head) != (element))); \ + GNUNET_assert (((element)->next_ ## mdll == NULL) && ((tail) != (element))); \ + (element)->next_ ## mdll = (other); \ + if (NULL == other) \ + { \ + (element)->prev = (tail); \ + (tail) = (element); \ + } \ + else \ + { \ + (element)->prev_ ## mdll = (other)->prev_ ## mdll; \ + (other)->prev_ ## mdll = (element); \ + } \ + if (NULL == (element)->prev_ ## mdll) \ + (head) = (element); \ + else \ + (element)->prev_ ## mdll->next_ ## mdll = (element); \ + } while (0) + + +/** + * @ingroup dll + * Remove an element from a MDLL. Assumes + * that head, tail and element are structs + * with prev and next fields. + * + * @param mdll suffix name for the next and prev pointers in the element + * @param head pointer to the head of the MDLL + * @param tail pointer to the tail of the MDLL + * @param element element to remove + */ +#define GNUNET_CONTAINER_MDLL_remove(mdll, head, tail, element) \ + do \ + { \ + GNUNET_assert (((element)->prev_ ## mdll != NULL) || ((head) == (element))); \ + GNUNET_assert (((element)->next_ ## mdll != NULL) || ((tail) == (element))); \ + if ((element)->prev_ ## mdll == NULL) \ + (head) = (element)->next_ ## mdll; \ + else \ + (element)->prev_ ## mdll->next_ ## mdll = (element)->next_ ## mdll; \ + if ((element)->next_ ## mdll == NULL) \ + (tail) = (element)->prev_ ## mdll; \ + else \ + (element)->next_ ## mdll->prev_ ## mdll = (element)->prev_ ## mdll; \ + (element)->next_ ## mdll = NULL; \ + (element)->prev_ ## mdll = NULL; \ + } while (0) + + +/** + * Insertion sort of @a element into DLL from @a head to @a tail + * sorted by @a comparator. + * + * @param TYPE element type of the elements, e.g. `struct ListElement` + * @param comparator function like memcmp() to compare elements; takes + * three arguments, the @a comparator_cls and two elements, + * returns an `int` (-1, 0 or 1) + * @param comparator_cls closure for @a comparator + * @param[in,out] head head of DLL + * @param[in,out] tail tail of DLL + * @param element element to insert + */ +#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, \ + comparator, \ + comparator_cls, \ + head, \ + tail, \ + element) \ + do \ + { \ + if ((NULL == head) || (0 < comparator (comparator_cls, element, head))) \ + { \ + /* insert at head, element < head */ \ + GNUNET_CONTAINER_DLL_insert (head, tail, element); \ + } \ + else \ + { \ + TYPE *pos; \ + \ + for (pos = head; NULL != pos; pos = pos->next) \ + if (0 < comparator (comparator_cls, element, pos)) \ + break; /* element < pos */ \ + if (NULL == pos) /* => element > tail */ \ + { \ + GNUNET_CONTAINER_DLL_insert_tail (head, tail, element); \ + } \ + else /* prev < element < pos */ \ + { \ + GNUNET_CONTAINER_DLL_insert_after (head, tail, pos->prev, element); \ + } \ + } \ + } while (0) + + +/* ******************** Heap *************** */ + + +/** + * @ingroup heap + * Cost by which elements in a heap can be ordered. + */ +typedef uint64_t GNUNET_CONTAINER_HeapCostType; + + +/** + * @ingroup heap + * Heap type, either max or min. + */ +enum GNUNET_CONTAINER_HeapOrder +{ + /** + * @ingroup heap + * Heap with the maximum cost at the root. + */ + GNUNET_CONTAINER_HEAP_ORDER_MAX, + + /** + * @ingroup heap + * Heap with the minimum cost at the root. + */ + GNUNET_CONTAINER_HEAP_ORDER_MIN +}; + + +/** + * @ingroup heap + * Handle to a Heap. + */ +struct GNUNET_CONTAINER_Heap; + + +/** + * @ingroup heap + * Handle to a node in a heap. + */ +struct GNUNET_CONTAINER_HeapNode; + + +/** + * @ingroup heap + * Create a new heap. + * + * @param order how should the heap be sorted? + * @return handle to the heap + */ +struct GNUNET_CONTAINER_Heap * +GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder order); + + +/** + * @ingroup heap + * Destroys the heap. Only call on a heap that + * is already empty. + * + * @param heap heap to destroy + */ +void +GNUNET_CONTAINER_heap_destroy (struct GNUNET_CONTAINER_Heap *heap); + + +/** + * @ingroup heap + * Get element stored at the root of @a heap. + * + * @param heap Heap to inspect. + * @return Element at the root, or NULL if heap is empty. + */ +void * +GNUNET_CONTAINER_heap_peek (const struct GNUNET_CONTAINER_Heap *heap); + + +/** + * Get @a element and @a cost stored at the root of @a heap. + * + * @param[in] heap Heap to inspect. + * @param[out] element Root element is returned here. + * @param[out] cost Cost of @a element is returned here. + * @return #GNUNET_YES if an element is returned, + * #GNUNET_NO if the heap is empty. + */ +enum GNUNET_GenericReturnValue +GNUNET_CONTAINER_heap_peek2 (const struct GNUNET_CONTAINER_Heap *heap, + void **element, + GNUNET_CONTAINER_HeapCostType *cost); + + +/** + * @ingroup heap + * Get the current size of the heap + * + * @param heap the heap to get the size of + * @return number of elements stored + */ +unsigned int +GNUNET_CONTAINER_heap_get_size (const struct GNUNET_CONTAINER_Heap *heap); + + +/** + * @ingroup heap + * Get the current cost of the node + * + * @param node the node to get the cost of + * @return cost of the node + */ +GNUNET_CONTAINER_HeapCostType +GNUNET_CONTAINER_heap_node_get_cost ( + const struct GNUNET_CONTAINER_HeapNode *node); + + +/** + * @ingroup heap + * Iterator for heap + * + * @param cls closure + * @param node internal node of the heap + * @param element value stored at the node + * @param cost cost associated with the node + * @return #GNUNET_YES if we should continue to iterate, + * #GNUNET_NO if not. + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_CONTAINER_HeapIterator)( + void *cls, + struct GNUNET_CONTAINER_HeapNode *node, + void *element, + GNUNET_CONTAINER_HeapCostType cost); + + +/** + * @ingroup heap + * Iterate over all entries in the heap. + * + * @param heap the heap + * @param iterator function to call on each entry + * @param iterator_cls closure for @a iterator + */ +void +GNUNET_CONTAINER_heap_iterate (const struct GNUNET_CONTAINER_Heap *heap, + GNUNET_CONTAINER_HeapIterator iterator, + void *iterator_cls); + +/** + * @ingroup heap + * Perform a random walk of the tree. The walk is biased + * towards elements closer to the root of the tree (since + * each walk starts at the root and ends at a random leaf). + * The heap internally tracks the current position of the + * walk. + * + * @param heap heap to walk + * @return data stored at the next random node in the walk; + * NULL if the tree is empty. + */ +void * +GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *heap); + + +/** + * @ingroup heap + * Inserts a new element into the heap. + * + * @param heap heap to modify + * @param element element to insert + * @param cost cost for the element + * @return node for the new element + */ +struct GNUNET_CONTAINER_HeapNode * +GNUNET_CONTAINER_heap_insert (struct GNUNET_CONTAINER_Heap *heap, + void *element, + GNUNET_CONTAINER_HeapCostType cost); + + +/** + * @ingroup heap + * Remove root of the heap. + * + * @param heap heap to modify + * @return element data stored at the root node + */ +void * +GNUNET_CONTAINER_heap_remove_root (struct GNUNET_CONTAINER_Heap *heap); + + +/** + * @ingroup heap + * Removes a node from the heap. + * + * @param node node to remove + * @return element data stored at the node, NULL if heap is empty + */ +void * +GNUNET_CONTAINER_heap_remove_node (struct GNUNET_CONTAINER_HeapNode *node); + + +/** + * @ingroup heap + * Updates the cost of any node in the tree + * + * @param node node for which the cost is to be changed + * @param new_cost new cost for the node + */ +void +GNUNET_CONTAINER_heap_update_cost (struct GNUNET_CONTAINER_HeapNode *node, + GNUNET_CONTAINER_HeapCostType new_cost); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + + +/* ifndef GNUNET_CONTAINER_LIB_H */ +#endif + +/** @} */ /* end of group addition */ + +/* end of gnunet_container_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_crypto_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_crypto_lib.h @@ -0,0 +1,4550 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-2023 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 + * @{ + * + * @file include/gnunet_crypto_lib.h + * @brief cryptographic primitives for GNUnet + * + * @author Christian Grothoff + * @author Krista Bennett + * @author Gerd Knorr <kraxel@bytesex.org> + * @author Ioana Patrascu + * @author Tzvetan Horozov + * @author Jeffrey Burdges <burdges@gnunet.org> + * + * @defgroup crypto Crypto library: cryptographic operations + * Provides cryptographic primitives. + * + * @see [Documentation](https://gnunet.org/crypto-api) + * + * @defgroup hash Crypto library: hash operations + * Provides hashing and operations on hashes. + * + * @see [Documentation](https://gnunet.org/crypto-api) + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_CRYPTO_LIB_H +#define GNUNET_CRYPTO_LIB_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include <stdbool.h> +#include <sodium.h> + +/** + * The identity of the host (wraps the signing key of the peer). + */ +struct GNUNET_PeerIdentity; + +#include <gcrypt.h> + + +/** + * Maximum length of an ECC signature. + * Note: round up to multiple of 8 minus 2 for alignment. + */ +#define GNUNET_CRYPTO_ECC_SIGNATURE_DATA_ENCODING_LENGTH 126 + + +/** + * Desired quality level for random numbers. + * @ingroup crypto + */ +enum GNUNET_CRYPTO_Quality +{ + /** + * No good quality of the operation is needed (i.e., + * random numbers can be pseudo-random). + * @ingroup crypto + */ + GNUNET_CRYPTO_QUALITY_WEAK, + + /** + * High-quality operations are desired. + * @ingroup crypto + */ + GNUNET_CRYPTO_QUALITY_STRONG, + + /** + * Randomness for IVs etc. is required. + * @ingroup crypto + */ + GNUNET_CRYPTO_QUALITY_NONCE +}; + + +/** + * @brief length of the sessionkey in bytes (256 BIT sessionkey) + */ +#define GNUNET_CRYPTO_AES_KEY_LENGTH (256 / 8) + +/** + * Length of a hash value + */ +#define GNUNET_CRYPTO_HASH_LENGTH (512 / 8) + +/** + * How many characters (without 0-terminator) are our ASCII-encoded + * public keys (ECDSA/EDDSA/ECDHE). + */ +#define GNUNET_CRYPTO_PKEY_ASCII_LENGTH 52 + +/** + * @brief 0-terminated ASCII encoding of a struct GNUNET_HashCode. + */ +struct GNUNET_CRYPTO_HashAsciiEncoded +{ + unsigned char encoding[104]; +}; + + +GNUNET_NETWORK_STRUCT_BEGIN + + +/** + * @brief header of what an ECC signature signs + * this must be followed by "size - 8" bytes of + * the actual signed data + */ +struct GNUNET_CRYPTO_EccSignaturePurpose +{ + /** + * How many bytes does this signature sign? + * (including this purpose header); in network + * byte order (!). + */ + uint32_t size GNUNET_PACKED; + + /** + * What does this signature vouch for? This + * must contain a GNUNET_SIGNATURE_PURPOSE_XXX + * constant (from gnunet_signatures.h). In + * network byte order! + */ + uint32_t purpose GNUNET_PACKED; +}; + + +/** + * @brief an ECC signature using EdDSA. + * See cr.yp.to/papers.html#ed25519 + */ +struct GNUNET_CRYPTO_EddsaSignature +{ + /** + * R value. + */ + unsigned char r[256 / 8]; + + /** + * S value. + */ + unsigned char s[256 / 8]; +}; + + +/** + * @brief an ECC signature using ECDSA + */ +struct GNUNET_CRYPTO_EcdsaSignature +{ + /** + * R value. + */ + unsigned char r[256 / 8]; + + /** + * S value. + */ + unsigned char s[256 / 8]; +}; + + +/** + * Public ECC key (always for curve Ed25519) encoded in a format + * suitable for network transmission and EdDSA signatures. Refer + * to section 5.1.3 of rfc8032, for a thorough explanation of how + * this value maps to the x- and y-coordinates. + */ +struct GNUNET_CRYPTO_EddsaPublicKey +{ + /** + * Point Q consists of a y-value mod p (256 bits); the x-value is + * always positive. The point is stored in Ed25519 standard + * compact format. + */ + unsigned char q_y[256 / 8]; +}; + + +/** + * Public ECC key (always for Curve25519) encoded in a format suitable + * for network transmission and ECDSA signatures. + */ +struct GNUNET_CRYPTO_EcdsaPublicKey +{ + /** + * Q consists of an x- and a y-value, each mod p (256 bits), given + * here in affine coordinates and Ed25519 standard compact format. + */ + unsigned char q_y[256 / 8]; +}; + + +/** + * The identity of the host (wraps the signing key of the peer). + */ +struct GNUNET_PeerIdentity +{ + struct GNUNET_CRYPTO_EddsaPublicKey public_key; +}; + + +/** + * Public ECC key (always for Curve25519) encoded in a format suitable + * for network transmission and encryption (ECDH), + * See http://cr.yp.to/ecdh.html + */ +struct GNUNET_CRYPTO_EcdhePublicKey +{ + /** + * Q consists of an x- and a y-value, each mod p (256 bits), given + * here in affine coordinates and Ed25519 standard compact format. + */ + unsigned char q_y[256 / 8]; +}; + + +/** + * Private ECC key encoded for transmission. To be used only for ECDH + * key exchange (ECDHE to be precise). + */ +struct GNUNET_CRYPTO_EcdhePrivateKey +{ + /** + * d is a value mod n, where n has at most 256 bits. + */ + unsigned char d[256 / 8]; +}; + +/** + * Private ECC key encoded for transmission. To be used only for ECDSA + * signatures. + */ +struct GNUNET_CRYPTO_EcdsaPrivateKey +{ + /** + * d is a value mod n, where n has at most 256 bits. + */ + unsigned char d[256 / 8]; +}; + +/** + * Private ECC key encoded for transmission. To be used only for EdDSA + * signatures. + */ +struct GNUNET_CRYPTO_EddsaPrivateKey +{ + /** + * d is a value mod n, where n has at most 256 bits. + */ + unsigned char d[256 / 8]; +}; + + +/** + * Private ECC scalar encoded for transmission. To be used only for EdDSA + * signatures. + */ +struct GNUNET_CRYPTO_EddsaPrivateScalar +{ + /** + * s is the expandedprivate 512-bit scalar of a private key. + */ + unsigned char s[512 / 8]; +}; + +/** + * Private ECC key material encoded for transmission. To be used only for + * Edx25519 signatures. An initial key corresponds to data from the key + * expansion and clamping in the EdDSA key generation. + */ +struct GNUNET_CRYPTO_Edx25519PrivateKey +{ + /** + * a is a value mod n, where n has at most 256 bits. It is the first half of + * the seed-expansion of EdDSA and will be clamped. + */ + unsigned char a[256 / 8]; + + /** + * b consists of 32 bytes which where originally the lower 32bytes of the key + * expansion. Subsequent calls to derive_private will change this value, too. + */ + unsigned char b[256 / 8]; +}; + + +/** + * Public ECC key (always for curve Ed25519) encoded in a format suitable for + * network transmission and Edx25519 (same as EdDSA) signatures. Refer to + * section 5.1.3 of rfc8032, for a thorough explanation of how this value maps + * to the x- and y-coordinates. + */ +struct GNUNET_CRYPTO_Edx25519PublicKey +{ + /** + * Point Q consists of a y-value mod p (256 bits); the x-value is + * always positive. The point is stored in Ed25519 standard + * compact format. + */ + unsigned char q_y[256 / 8]; +}; + +/** + * @brief an ECC signature using Edx25519 (same as in EdDSA). + */ +struct GNUNET_CRYPTO_Edx25519Signature +{ + /** + * R value. + */ + unsigned char r[256 / 8]; + + /** + * S value. + */ + unsigned char s[256 / 8]; +}; + +/** + * Elligator representative (always for Curve25519) + */ +struct GNUNET_CRYPTO_ElligatorRepresentative +{ + /** + * Represents an element of Curve25519 finite field. + * Always smaller than 2 ^ 254 - 10 -> Needs to be serialized into a random-looking byte stream before transmission. + */ + unsigned char r[256 / 8]; +}; + +/** + * Key type for the generic public key union + */ +enum GNUNET_CRYPTO_KeyType +{ + /** + * The identity type. The value is the same as the + * PKEY record type. + */ + GNUNET_PUBLIC_KEY_TYPE_ECDSA = 65536, + + /** + * EDDSA identity. The value is the same as the EDKEY + * record type. + */ + GNUNET_PUBLIC_KEY_TYPE_EDDSA = 65556 +}; + +/** + * A private key for an identity as per LSD0001. + * Note that these types are NOT packed and MUST NOT be used in RPC + * messages. Use the respective serialization functions. + */ +struct GNUNET_CRYPTO_PrivateKey +{ + /** + * Type of public key. + * Defined by the GNS zone type value. + * In NBO. + */ + uint32_t type; + + union + { + /** + * An ECDSA identity key. + */ + struct GNUNET_CRYPTO_EcdsaPrivateKey ecdsa_key; + + /** + * AN EdDSA identtiy key + */ + struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_key; + }; +}; + + +/** + * An identity key as per LSD0001. + */ +struct GNUNET_CRYPTO_PublicKey +{ + /** + * Type of public key. + * Defined by the GNS zone type value. + * In NBO. + */ + uint32_t type; + + union + { + /** + * An ECDSA identity key. + */ + struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_key; + + /** + * AN EdDSA identtiy key + */ + struct GNUNET_CRYPTO_EddsaPublicKey eddsa_key; + }; +}; + + +/** + * An identity signature as per LSD0001. + */ +struct GNUNET_CRYPTO_Signature +{ + /** + * Type of signature. + * Defined by the GNS zone type value. + * In NBO. + */ + uint32_t type; + + union + { + /** + * An ECDSA signature + */ + struct GNUNET_CRYPTO_EcdsaSignature ecdsa_signature; + + /** + * AN EdDSA signature + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; + }; +}; + +/** + * @brief type for session keys + */ +struct GNUNET_CRYPTO_SymmetricSessionKey +{ + /** + * Actual key for AES. + */ + unsigned char aes_key[GNUNET_CRYPTO_AES_KEY_LENGTH]; + + /** + * Actual key for TwoFish. + */ + unsigned char twofish_key[GNUNET_CRYPTO_AES_KEY_LENGTH]; +}; + +/** + * Type of a nonce used for challenges. + */ +struct GNUNET_CRYPTO_ChallengeNonceP +{ + /** + * The value of the nonce. Note that this is NOT a hash. + */ + struct GNUNET_ShortHashCode value; +}; + +GNUNET_NETWORK_STRUCT_END + +/** + * @brief IV for sym cipher + * + * NOTE: must be smaller (!) in size than the + * `struct GNUNET_HashCode`. + */ +struct GNUNET_CRYPTO_SymmetricInitializationVector +{ + unsigned char aes_iv[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; + + unsigned char twofish_iv[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; +}; + + +/** + * @brief type for (message) authentication keys + */ +struct GNUNET_CRYPTO_AuthKey +{ + unsigned char key[GNUNET_CRYPTO_HASH_LENGTH]; +}; + + +/** + * Size of paillier plain texts and public keys. + * Private keys and ciphertexts are twice this size. + */ +#define GNUNET_CRYPTO_PAILLIER_BITS 2048 + + +/** + * Paillier public key. + */ +struct GNUNET_CRYPTO_PaillierPublicKey +{ + /** + * N value. + */ + unsigned char n[GNUNET_CRYPTO_PAILLIER_BITS / 8]; +}; + + +/** + * Paillier private key. + */ +struct GNUNET_CRYPTO_PaillierPrivateKey +{ + /** + * Lambda-component of the private key. + */ + unsigned char lambda[GNUNET_CRYPTO_PAILLIER_BITS / 8]; + /** + * Mu-component of the private key. + */ + unsigned char mu[GNUNET_CRYPTO_PAILLIER_BITS / 8]; +}; + + +/** + * Paillier ciphertext. + */ +struct GNUNET_CRYPTO_PaillierCiphertext +{ + /** + * Guaranteed minimum number of homomorphic operations with this ciphertext, + * in network byte order (NBO). + */ + int32_t remaining_ops GNUNET_PACKED; + + /** + * The bits of the ciphertext. + */ + unsigned char bits[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8]; +}; + + +/** + * Curve25519 Scalar + */ +struct GNUNET_CRYPTO_Cs25519Scalar +{ + /** + * 32 byte scalar + */ + unsigned char d[crypto_core_ed25519_SCALARBYTES]; +}; + + +/** + * Curve25519 point + */ +struct GNUNET_CRYPTO_Cs25519Point +{ + /** + * This is a point on the Curve25519. + * The x coordinate can be restored using the y coordinate + */ + unsigned char y[crypto_core_ed25519_BYTES]; +}; + + +/** + * The private information of an Schnorr key pair. + */ +struct GNUNET_CRYPTO_CsPrivateKey +{ + struct GNUNET_CRYPTO_Cs25519Scalar scalar; +}; + + +/** + * The public information of an Schnorr key pair. + */ +struct GNUNET_CRYPTO_CsPublicKey +{ + struct GNUNET_CRYPTO_Cs25519Point point; +}; + + +/** + * Secret used for blinding (alpha and beta). + */ +struct GNUNET_CRYPTO_CsBlindingSecret +{ + struct GNUNET_CRYPTO_Cs25519Scalar alpha; + struct GNUNET_CRYPTO_Cs25519Scalar beta; +}; + + +/** + * the private r used in the signature + */ +struct GNUNET_CRYPTO_CsRSecret +{ + struct GNUNET_CRYPTO_Cs25519Scalar scalar; +}; + + +/** + * the public R (derived from r) used in c + */ +struct GNUNET_CRYPTO_CsRPublic +{ + struct GNUNET_CRYPTO_Cs25519Point point; +}; + + +/** + * Schnorr c to be signed + */ +struct GNUNET_CRYPTO_CsC +{ + struct GNUNET_CRYPTO_Cs25519Scalar scalar; +}; + + +/** + * s in the signature + */ +struct GNUNET_CRYPTO_CsS +{ + struct GNUNET_CRYPTO_Cs25519Scalar scalar; +}; + + +/** + * blinded s in the signature + */ +struct GNUNET_CRYPTO_CsBlindS +{ + struct GNUNET_CRYPTO_Cs25519Scalar scalar; +}; + + +/** + * CS Signtature containing scalar s and point R + */ +struct GNUNET_CRYPTO_CsSignature +{ + /** + * Schnorr signatures are composed of a scalar s and a curve point + */ + struct GNUNET_CRYPTO_CsS s_scalar; + + /** + * Curve point of the Schnorr signature. + */ + struct GNUNET_CRYPTO_CsRPublic r_point; +}; + + +/** + * Nonce for the session, picked by client, + * shared with the signer. + */ +struct GNUNET_CRYPTO_CsSessionNonce +{ + /*a nonce*/ + unsigned char snonce[256 / 8]; +}; + + +/** + * Nonce for computing blinding factors. Not + * shared with the signer. + */ +struct GNUNET_CRYPTO_CsBlindingNonce +{ + /*a nonce*/ + unsigned char bnonce[256 / 8]; +}; + + +/* **************** Functions and Macros ************* */ + +/** + * @ingroup crypto + * Seed a weak random generator. Only #GNUNET_CRYPTO_QUALITY_WEAK-mode generator + * can be seeded. + * + * @param seed the seed to use + */ +void +GNUNET_CRYPTO_seed_weak_random (int32_t seed); + + +/** + * @ingroup hash + * Calculate the checksum of a buffer in one step. + * + * @param buf buffer to calculate CRC over + * @param len number of bytes in @a buf + * @return crc8 value + */ +uint8_t +GNUNET_CRYPTO_crc8_n (const void *buf, size_t len); + + +/** + * Perform an incremental step in a CRC16 (for TCP/IP) calculation. + * + * @param sum current sum, initially 0 + * @param buf buffer to calculate CRC over (must be 16-bit aligned) + * @param len number of bytes in @a buf, must be multiple of 2 + * @return updated crc sum (must be subjected to #GNUNET_CRYPTO_crc16_finish to get actual crc16) + */ +uint32_t +GNUNET_CRYPTO_crc16_step (uint32_t sum, const void *buf, size_t len); + + +/** + * Convert results from GNUNET_CRYPTO_crc16_step to final crc16. + * + * @param sum cumulative sum + * @return crc16 value + */ +uint16_t +GNUNET_CRYPTO_crc16_finish (uint32_t sum); + + +/** + * @ingroup hash + * Calculate the checksum of a buffer in one step. + * + * @param buf buffer to calculate CRC over (must be 16-bit aligned) + * @param len number of bytes in @a buf, must be multiple of 2 + * @return crc16 value + */ +uint16_t +GNUNET_CRYPTO_crc16_n (const void *buf, size_t len); + + +/** + * @ingroup hash + * Compute the CRC32 checksum for the first len + * bytes of the buffer. + * + * @param buf the data over which we're taking the CRC + * @param len the length of the buffer @a buf in bytes + * @return the resulting CRC32 checksum + */ +int32_t +GNUNET_CRYPTO_crc32_n (const void *buf, size_t len); + +/** + * @ingroup crypto + * Zero out @a buffer, securely against compiler optimizations. + * Used to delete key material. + * + * @param buffer the buffer to zap + * @param length buffer length + */ +void +GNUNET_CRYPTO_zero_keys (void *buffer, size_t length); + + +/** + * @ingroup crypto + * Fill block with a random values. + * + * @param mode desired quality of the random number + * @param[out] buffer the buffer to fill + * @param length buffer length + */ +void +GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, + void *buffer, + size_t length); + + +/** + * @ingroup crypto + * Fill UUID with a timeflake pseudo-random value. Note that + * timeflakes use only 80 bits of randomness and 48 bits + * to encode a timestamp in milliseconds. So what we return + * here is not a completely random number. + * + * @param mode desired quality of the random number + * @param[out] uuid the value to fill + */ +void +GNUNET_CRYPTO_random_timeflake (enum GNUNET_CRYPTO_Quality mode, + struct GNUNET_Uuid *uuid); + + +/** + * @ingroup crypto + * Produce a random value. + * + * @param mode desired quality of the random number + * @param i the upper limit (exclusive) for the random number + * @return a random value in the interval [0,@a i) (exclusive). + */ +uint32_t +GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i); + + +/** + * @ingroup crypto + * Generate a random unsigned 64-bit value. + * + * @param mode desired quality of the random number + * @param max value returned will be in range [0,@a max) (exclusive) + * @return random 64-bit number + */ +uint64_t +GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max); + + +/** + * @ingroup crypto + * Get an array with a random permutation of the + * numbers 0...n-1. + * @param mode #GNUNET_CRYPTO_QUALITY_STRONG if the strong (but expensive) PRNG should be used, + * #GNUNET_CRYPTO_QUALITY_WEAK or #GNUNET_CRYPTO_QUALITY_NONCE otherwise + * @param n the size of the array + * @return the permutation array (allocated from heap) + */ +unsigned int * +GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n); + + +/** + * @ingroup crypto + * Create a new random session key. + * + * @param key key to initialize + */ +void +GNUNET_CRYPTO_symmetric_create_session_key ( + struct GNUNET_CRYPTO_SymmetricSessionKey *key); + + +/** + * @ingroup crypto + * Encrypt a block using a symmetric sessionkey. + * + * @param block the block to encrypt + * @param size the size of the @a block + * @param sessionkey the key used to encrypt + * @param iv the initialization vector to use, use INITVALUE + * for streams. + * @return the size of the encrypted block, -1 for errors + */ +ssize_t +GNUNET_CRYPTO_symmetric_encrypt ( + const void *block, + size_t size, + const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, + const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, + void *result); + + +/** + * @ingroup crypto + * Decrypt a given block using a symmetric sessionkey. + * + * @param block the data to decrypt, encoded as returned by encrypt + * @param size how big is the block? + * @param sessionkey the key used to decrypt + * @param iv the initialization vector to use + * @param result address to store the result at + * @return -1 on failure, size of decrypted block on success + */ +ssize_t +GNUNET_CRYPTO_symmetric_decrypt ( + const void *block, + size_t size, + const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, + const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, + void *result); + + +/** + * @ingroup crypto + * @brief Derive an IV + * @param iv initialization vector + * @param skey session key + * @param salt salt for the derivation + * @param salt_len size of the @a salt + * @param ... pairs of void * & size_t for context chunks, terminated by NULL + */ +void +GNUNET_CRYPTO_symmetric_derive_iv ( + struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, + const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, + const void *salt, + size_t salt_len, + ...); + + +/** + * @brief Derive an IV + * @param iv initialization vector + * @param skey session key + * @param salt salt for the derivation + * @param salt_len size of the @a salt + * @param argp pairs of void * & size_t for context chunks, terminated by NULL + */ +void +GNUNET_CRYPTO_symmetric_derive_iv_v ( + struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, + const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, + const void *salt, + size_t salt_len, + va_list argp); + + +/** + * @ingroup hash + * Convert hash to ASCII encoding. + * @param block the hash code + * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be + * safely cast to char*, a '\\0' termination is set). + */ +void +GNUNET_CRYPTO_hash_to_enc (const struct GNUNET_HashCode *block, + struct GNUNET_CRYPTO_HashAsciiEncoded *result); + + +/** + * @ingroup hash + * Convert ASCII encoding back to a 'struct GNUNET_HashCode' + * + * @param enc the encoding + * @param enclen number of characters in @a enc (without 0-terminator, which can be missing) + * @param result where to store the hash code + * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_hash_from_string2 (const char *enc, + size_t enclen, + struct GNUNET_HashCode *result); + + +/** + * @ingroup hash + * Convert ASCII encoding back to `struct GNUNET_HashCode` + * + * @param enc the encoding + * @param result where to store the hash code + * @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) + + +/** + * @ingroup hash + * + * Compute the distance between 2 hashcodes. The + * computation must be fast, not involve @a a[0] or @a a[4] (they're used + * elsewhere), and be somewhat consistent. And of course, the result + * should be a positive number. + * + * @param a some hash code + * @param b some hash code + * @return number between 0 and UINT32_MAX + */ +uint32_t +GNUNET_CRYPTO_hash_distance_u32 (const struct GNUNET_HashCode *a, + const struct GNUNET_HashCode *b); + + +/** + * @ingroup hash + * Compute hash of a given block. + * + * @param block the data to hash + * @param size size of the @a block + * @param ret pointer to where to write the hashcode + */ +void +GNUNET_CRYPTO_hash (const void *block, + size_t size, + struct GNUNET_HashCode *ret); + + +/** + * Value for a salt for #GNUNET_CRYPTO_pow_hash(). + */ +struct GNUNET_CRYPTO_PowSalt +{ + char salt[crypto_pwhash_argon2id_SALTBYTES]; +}; + + +/** + * Calculate the 'proof-of-work' hash (an expensive hash). + * + * @param salt salt for the hash. Must be crypto_pwhash_argon2id_SALTBYTES long. + * @param buf data to hash + * @param buf_len number of bytes in @a buf + * @param result where to write the resulting hash + */ +void +GNUNET_CRYPTO_pow_hash (const struct GNUNET_CRYPTO_PowSalt *salt, + const void *buf, + size_t buf_len, + struct GNUNET_HashCode *result); + + +/** + * Context for cumulative hashing. + */ +struct GNUNET_HashContext; + + +/** + * Start incremental hashing operation. + * + * @return context for incremental hash computation + */ +struct GNUNET_HashContext * +GNUNET_CRYPTO_hash_context_start (void); + + +/** + * Make a copy of the hash computation. + * + * @param hc hash context to use (to continue hashing independently) + * @return copy of @a hc + */ +struct GNUNET_HashContext * +GNUNET_CRYPTO_hash_context_copy (const struct GNUNET_HashContext *hc); + + +/** + * Add data to be hashed. + * + * @param hc cumulative hash context + * @param buf data to add + * @param size number of bytes in @a buf + */ +void +GNUNET_CRYPTO_hash_context_read (struct GNUNET_HashContext *hc, + const void *buf, + size_t size); + + +/** + * Finish the hash computation. + * + * @param hc hash context to use, is freed in the process + * @param r_hash where to write the latest / final hash code + */ +void +GNUNET_CRYPTO_hash_context_finish (struct GNUNET_HashContext *hc, + struct GNUNET_HashCode *r_hash); + + +/** + * Abort hashing, do not bother calculating final result. + * + * @param hc hash context to destroy + */ +void +GNUNET_CRYPTO_hash_context_abort (struct GNUNET_HashContext *hc); + + +/** + * Calculate HMAC of a message (RFC 2104) + * TODO: Shouldn't this be the standard hmac function and + * the above be renamed? + * + * @param key secret key + * @param key_len secret key length + * @param plaintext input plaintext + * @param plaintext_len length of @a plaintext + * @param hmac where to store the hmac + */ +void +GNUNET_CRYPTO_hmac_raw (const void *key, + size_t key_len, + const void *plaintext, + size_t plaintext_len, + struct GNUNET_HashCode *hmac); + + +/** + * @ingroup hash + * Calculate HMAC of a message (RFC 2104) + * + * @param key secret key + * @param plaintext input plaintext + * @param plaintext_len length of @a plaintext + * @param hmac where to store the hmac + */ +void +GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, + const void *plaintext, + size_t plaintext_len, + struct GNUNET_HashCode *hmac); + + +/** + * Function called once the hash computation over the + * specified file has completed. + * + * @param cls closure + * @param res resulting hash, NULL on error + */ +typedef void +(*GNUNET_CRYPTO_HashCompletedCallback) ( + void *cls, + const struct GNUNET_HashCode *res); + + +/** + * Handle to file hashing operation. + */ +struct GNUNET_CRYPTO_FileHashContext; + + +/** + * @ingroup hash + * Compute the hash of an entire file. + * + * @param priority scheduling priority to use + * @param filename name of file to hash + * @param blocksize number of bytes to process in one task + * @param callback function to call upon completion + * @param callback_cls closure for @a callback + * @return NULL on (immediate) error + */ +struct GNUNET_CRYPTO_FileHashContext * +GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority, + const char *filename, + size_t blocksize, + GNUNET_CRYPTO_HashCompletedCallback callback, + void *callback_cls); + + +/** + * Cancel a file hashing operation. + * + * @param fhc operation to cancel (callback must not yet have been invoked) + */ +void +GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc); + + +/** + * @ingroup hash + * Create a random hash code. + * + * @param mode desired quality level + * @param result hash code that is randomized + */ +void +GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, + struct GNUNET_HashCode *result); + + +/** + * @ingroup hash + * compute @a result = @a b - @a a + * + * @param a some hash code + * @param b some hash code + * @param result set to @a b - @a a + */ +void +GNUNET_CRYPTO_hash_difference (const struct GNUNET_HashCode *a, + const struct GNUNET_HashCode *b, + struct GNUNET_HashCode *result); + + +/** + * @ingroup hash + * compute @a result = @a a + @a delta + * + * @param a some hash code + * @param delta some hash code + * @param result set to @a a + @a delta + */ +void +GNUNET_CRYPTO_hash_sum (const struct GNUNET_HashCode *a, + const struct GNUNET_HashCode *delta, + struct GNUNET_HashCode *result); + + +/** + * @ingroup hash + * compute result = a ^ b + * + * @param a some hash code + * @param b some hash code + * @param result set to @a a ^ @a b + */ +void +GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode *a, + const struct GNUNET_HashCode *b, + struct GNUNET_HashCode *result); + + +/** + * Count the number of leading 0 bits in @a h. + * + * @param h a hash + * @return number of leading 0 bits in @a h + */ +unsigned int +GNUNET_CRYPTO_hash_count_leading_zeros (const struct GNUNET_HashCode *h); + + +/** + * Count the number of tailing 0 bits in @a h. + * + * @param h a hash + * @return number of tailing 0 bits in @a h + */ +unsigned int +GNUNET_CRYPTO_hash_count_tailing_zeros (const struct GNUNET_HashCode *h); + + +/** + * @ingroup hash + * Convert a hashcode into a key. + * + * @param hc hash code that serves to generate the key + * @param skey set to a valid session key + * @param iv set to a valid initialization vector + */ +void +GNUNET_CRYPTO_hash_to_aes_key ( + const struct GNUNET_HashCode *hc, + struct GNUNET_CRYPTO_SymmetricSessionKey *skey, + struct GNUNET_CRYPTO_SymmetricInitializationVector *iv); + + +/** + * @ingroup hash + * Compare function for HashCodes, producing a total ordering + * of all hashcodes. + * + * @param h1 some hash code + * @param h2 some hash code + * @return 1 if @a h1 > @a h2, -1 if @a h1 < @a h2 and 0 if @a h1 == @a h2. + */ +int +GNUNET_CRYPTO_hash_cmp (const struct GNUNET_HashCode *h1, + const struct GNUNET_HashCode *h2); + + +/** + * @ingroup hash + * Find out which of the two GNUNET_CRYPTO_hash codes is closer to target + * in the XOR metric (Kademlia). + * + * @param h1 some hash code + * @param h2 some hash code + * @param target some hash code + * @return -1 if @a h1 is closer, 1 if @a h2 is closer and 0 if @a h1== @a h2. + */ +int +GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1, + const struct GNUNET_HashCode *h2, + const struct GNUNET_HashCode *target); + + +/** + * @ingroup hash + * @brief Derive an authentication key + * @param key authentication key + * @param rkey root key + * @param salt salt + * @param salt_len size of the salt + * @param argp pair of void * & size_t for context chunks, terminated by NULL + */ +void +GNUNET_CRYPTO_hmac_derive_key_v ( + struct GNUNET_CRYPTO_AuthKey *key, + const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, + const void *salt, + size_t salt_len, + va_list argp); + + +/** + * @ingroup hash + * @brief Derive an authentication key + * @param key authentication key + * @param rkey root key + * @param salt salt + * @param salt_len size of the salt + * @param ... pair of void * & size_t for context chunks, terminated by NULL + */ +void +GNUNET_CRYPTO_hmac_derive_key ( + struct GNUNET_CRYPTO_AuthKey *key, + const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, + const void *salt, + size_t salt_len, + ...); + + +/** + * @ingroup hash + * @brief HKDF-Extract using SHA256. RFC 5869 + * @param prk the PRK + * @param salt salt + * @param salt_len length of @a xts + * @param ikm source key material + * @param ikm_len length of @a skm + * @return #GNUNET_YES on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_hkdf_extract (struct GNUNET_ShortHashCode *prk, + const void *salt, + size_t salt_len, + const void *ikm, + size_t ikm_len); + +/** + * @ingroup hash + * @brief HKDF-Expand using SHA256. RFC 5869 + * @param result buffer for the derived key, allocated by caller + * @param out_len desired length of the derived key + * @param ... pair of void * & size_t for context chunks, terminated by NULL + * @return #GNUNET_YES on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_hkdf_expand (void *result, + size_t out_len, + const struct GNUNET_ShortHashCode *prk, + ...); + +/** + * @ingroup hash + * @brief HKDF-Expand using SHA256. See #GNUNET_CRYPTO_hkdf_expand + * @param result buffer for the derived key, allocated by caller + * @param out_len desired length of the derived key + * @param argp va_list of void * & size_t pairs for context chunks + * @return #GNUNET_YES on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_hkdf_expand_v (void *result, + size_t out_len, + const struct GNUNET_ShortHashCode *prk, + va_list argp); + + +/** + * @ingroup hash + * @brief A peculiar HKDF instantiation that tried to mimic Truncated NMAC. + * But, what it actually does is HKDF-Extract with SHA512 and instead of + * truncating the PRK, it uses it as a 64 byte key in the HKDF-Expand + * phase with SHA256. + * (Truncated NMAC would require us to, well, truncate it to 32 byte.) + * ONLY USE FOR COMPATIBLITY WITH OLDER KEY DERIVATIONS. + * Use the more standard #GNUNET_CRYPTO_hkdf_extract and + * #GNUNET_CRYPTO_HKDF_expand instead! + * + * @param result buffer for the derived key, allocated by caller + * @param out_len desired length of the derived key + * @param xts salt + * @param xts_len length of @a xts + * @param skm source key material + * @param skm_len length of @a skm + * @param ... pair of void * & size_t for context chunks, terminated by NULL + * @return #GNUNET_YES on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_hkdf_gnunet (void *result, + size_t out_len, + const void *xts, + size_t xts_len, + const void *skm, + size_t skm_len, + ...); + + +/** + * @ingroup hash + * @brief Derive key. See #GNUNET_CRYPTO_hkdf_gnunet + * @param result buffer for the derived key, allocated by caller + * @param out_len desired length of the derived key + * @param xts salt + * @param xts_len length of @a xts + * @param skm source key material + * @param skm_len length of @a skm + * @param argp va_list of void * & size_t pairs for context chunks + * @return #GNUNET_YES on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_hkdf_gnunet_v (void *result, + size_t out_len, + const void *xts, + size_t xts_len, + const void *skm, + size_t skm_len, + va_list argp); + + +/** + * @brief Derive key + * @param result buffer for the derived key, allocated by caller + * @param out_len desired length of the derived key + * @param xts salt + * @param xts_len length of @a xts + * @param skm source key material + * @param skm_len length of @a skm + * @param argp va_list of void * & size_t pairs for context chunks + * @return #GNUNET_YES on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_kdf_v (void *result, + size_t out_len, + const void *xts, + size_t xts_len, + const void *skm, + size_t skm_len, + va_list argp); + + +/** + * Deterministically generate a pseudo-random number uniformly from the + * integers modulo a libgcrypt mpi. + * + * @param[out] r MPI value set to the FDH + * @param n MPI to work modulo + * @param xts salt + * @param xts_len length of @a xts + * @param skm source key material + * @param skm_len length of @a skm + * @param ctx context string + */ +void +GNUNET_CRYPTO_kdf_mod_mpi (gcry_mpi_t *r, + gcry_mpi_t n, + const void *xts, + size_t xts_len, + const void *skm, + size_t skm_len, + const char *ctx); + + +/** + * @ingroup hash + * @brief Derive key + * @param result buffer for the derived key, allocated by caller + * @param out_len desired length of the derived key + * @param xts salt + * @param xts_len length of @a xts + * @param skm source key material + * @param skm_len length of @a skm + * @param ... void * & size_t pairs for context chunks + * @return #GNUNET_YES on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_kdf (void *result, + size_t out_len, + const void *xts, + size_t xts_len, + const void *skm, + size_t skm_len, + ...); + + +/** + * @ingroup crypto + * Extract the public key for the given private key. + * + * @param priv the private key + * @param pub where to write the public key + */ +void +GNUNET_CRYPTO_ecdsa_key_get_public ( + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, + struct GNUNET_CRYPTO_EcdsaPublicKey *pub); + +/** + * @ingroup crypto + * Extract the public key for the given private key. + * + * @param priv the private key + * @param pub where to write the public key + */ +void +GNUNET_CRYPTO_eddsa_key_get_public ( + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + struct GNUNET_CRYPTO_EddsaPublicKey *pub); + +/** + * @ingroup crypto + * Extract the public key for the given private key. + * + * @param priv the private key + * @param pub where to write the public key + */ +void +GNUNET_CRYPTO_edx25519_key_get_public ( + const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, + struct GNUNET_CRYPTO_Edx25519PublicKey *pub); + +/** + * @ingroup crypto + * Extract the public key for the given private key. + * + * @param priv the private key + * @param pub where to write the public key + */ +void +GNUNET_CRYPTO_ecdhe_key_get_public ( + const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, + struct GNUNET_CRYPTO_EcdhePublicKey *pub); + + +/** + * Convert a public key to a string. + * + * @param pub key to convert + * @return string representing @a pub + */ +char * +GNUNET_CRYPTO_ecdsa_public_key_to_string ( + const struct GNUNET_CRYPTO_EcdsaPublicKey *pub); + +/** + * Convert a private key to a string. + * + * @param priv key to convert + * @return string representing @a priv + */ +char * +GNUNET_CRYPTO_ecdsa_private_key_to_string ( + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv); + + +/** + * Convert a private key to a string. + * + * @param priv key to convert + * @return string representing @a pub + */ +char * +GNUNET_CRYPTO_eddsa_private_key_to_string ( + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv); + + +/** + * Convert a public key to a string. + * + * @param pub key to convert + * @return string representing @a pub + */ +char * +GNUNET_CRYPTO_eddsa_public_key_to_string ( + const struct GNUNET_CRYPTO_EddsaPublicKey *pub); + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in @a enc (without 0-terminator) + * @param pub where to store the public key + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_public_key_from_string ( + const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_EcdsaPublicKey *pub); + + +/** + * Convert a string representing a private key to a private key. + * + * @param enc encoded public key + * @param enclen number of bytes in @a enc (without 0-terminator) + * @param priv where to store the private key + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_private_key_from_string ( + const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_EddsaPrivateKey *priv); + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in @a enc (without 0-terminator) + * @param pub where to store the public key + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_public_key_from_string ( + const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_EddsaPublicKey *pub); + + +/** + * @ingroup crypto + * @brief Create a new private key by reading it from a file. + * + * If the files does not exist and @a do_create is set, creates a new key and + * write it to the file. + * + * If the contents of the file are invalid, an error is returned. + * + * @param filename name of file to use to store the key + * @param do_create should a file be created? + * @param[out] pkey set to the private key from @a filename on success + * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but + * we found an existing file, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_key_from_file (const char *filename, + int do_create, + struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey); + + +/** + * @ingroup crypto + * @brief Create a new private key by reading it from a file. + * + * If the files does not exist and @a do_create is set, creates a new key and + * write it to the file. + * + * If the contents of the file are invalid, an error is returned. + * + * @param filename name of file to use to store the key + * @param do_create should a file be created? + * @param[out] pkey set to the private key from @a filename on success + * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but + * we found an existing file, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_key_from_file (const char *filename, + int do_create, + struct GNUNET_CRYPTO_EddsaPrivateKey *pkey); + + +/** + * Forward declaration to simplify #include-structure. + */ +struct GNUNET_CONFIGURATION_Handle; + + +/** + * @ingroup crypto + * Create a new private key by reading our peer's key from + * the file specified in the configuration. + * + * @param cfg the configuration to use + * @return new private key, NULL on error (for example, + * permission denied); free using #GNUNET_free + */ +struct GNUNET_CRYPTO_EddsaPrivateKey * +GNUNET_CRYPTO_eddsa_key_create_from_configuration ( + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * @ingroup crypto + * Create a new private key. + * + * @param[out] pk private key to initialize + */ +void +GNUNET_CRYPTO_ecdsa_key_create (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk); + + +/** + * @ingroup crypto + * Create a new private key. + * + * @param[out] pk private key to initialize + */ +void +GNUNET_CRYPTO_eddsa_key_create (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); + + +/** + * @ingroup crypto + * Create a new private key. + * + * @param[out] pk private key to initialize + */ +void +GNUNET_CRYPTO_edx25519_key_create (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); + +/** + * @ingroup crypto + * Create a new private key for Edx25519 from a given seed. After expanding + * the seed, the first half of the key will be clamped according to EdDSA. + * + * @param seed seed input + * @param seedsize size of the seed in bytes + * @param[out] pk private key to initialize + */ +void +GNUNET_CRYPTO_edx25519_key_create_from_seed ( + const void *seed, + size_t seedsize, + struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); + +/** + * @ingroup crypto + * Create a new private key. Clear with #GNUNET_CRYPTO_ecdhe_key_clear(). + * This is X25519 DH (RFC 7748 Section 5) and corresponds to + * X25519(a,9). + * See #GNUNET_CRYPTO_ecc_ecdh for the DH function. + * + * @param[out] pk set to fresh private key; + */ +void +GNUNET_CRYPTO_ecdhe_key_create (struct GNUNET_CRYPTO_EcdhePrivateKey *pk); + + +/** + * @ingroup crypto + * Clear memory that was used to store a private key. + * + * @param pk location of the key + */ +void +GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); + + +/** + * @ingroup crypto + * Clear memory that was used to store a private key. + * + * @param pk location of the key + */ +void +GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk); + +/** + * @ingroup crypto + * Clear memory that was used to store a private key. + * + * @param pk location of the key + */ +void +GNUNET_CRYPTO_edx25519_key_clear (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); + +/** + * @ingroup crypto + * Clear memory that was used to store a private key. + * + * @param pk location of the key + */ +void +GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk); + +/** + * @ingroup crypto + * Clear memory that was used to store a private key. + * + * @param pk location of the key + */ +void +GNUNET_CRYPTO_private_key_clear (struct GNUNET_CRYPTO_PrivateKey *pk); + + +/** + * @ingroup crypto + * Get the shared private key we use for anonymous users. + * + * @return "anonymous" private key; do not free + */ +const struct GNUNET_CRYPTO_EcdsaPrivateKey * +GNUNET_CRYPTO_ecdsa_key_get_anonymous (void); + + +/** + * @ingroup crypto + * Setup a hostkey file for a peer given the name of the + * configuration file (!). This function is used so that + * at a later point code can be certain that reading a + * hostkey is fast (for example in time-dependent testcases). + * + * @param cfg_name name of the configuration file to use + */ +void +GNUNET_CRYPTO_eddsa_setup_hostkey (const char *cfg_name); + + +/** + * @ingroup crypto + * Retrieve the identity of the host's peer. + * + * @param cfg configuration to use + * @param dst pointer to where to write the peer identity + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity + * could not be retrieved + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_PeerIdentity *dst); + + +/** + * @ingroup crypto + * Sign a given block with a specific purpose using the host's peer identity. + * + * @param cfg configuration to use + * @param purpose what to sign (size, purpose) + * @param sig where to write the signature + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity + * could not be retrieved + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_sign_by_peer_identity (const struct + GNUNET_CONFIGURATION_Handle *cfg, + const struct + GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_EddsaSignature *sig); + + +/** + * @ingroup crypto + * Verify a given signature with a peer's identity. + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param identity the peer's identity to verify + * @return #GNUNET_OK if ok, #GNUNET_SYSERR if invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_verify_peer_identity (uint32_t purpose, + const struct + GNUNET_CRYPTO_EccSignaturePurpose *validate, + const struct + GNUNET_CRYPTO_EddsaSignature *sig, + const struct GNUNET_PeerIdentity *identity); + + +/** + * Internal structure used to cache pre-calculated values for DLOG calculation. + */ +struct GNUNET_CRYPTO_EccDlogContext; + + +/** + * Point on a curve (always for Curve25519) encoded in a format suitable + * for network transmission (ECDH), see http://cr.yp.to/ecdh.html. + */ +struct GNUNET_CRYPTO_EccPoint +{ + /** + * Q consists of an x- and a y-value, each mod p (256 bits), given + * here in affine coordinates and Ed25519 standard compact format. + */ + unsigned char v[256 / 8]; +}; + +/** + * A ECC scalar for use in point multiplications + */ +struct GNUNET_CRYPTO_EccScalar +{ + unsigned char v[256 / 8]; +}; + +/** + * Do pre-calculation for ECC discrete logarithm for small factors. + * + * @param max maximum value the factor can be + * @param mem memory to use (should be smaller than @a max), must not be zero. + * @return NULL on error + */ +struct GNUNET_CRYPTO_EccDlogContext * +GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, + unsigned int mem); + + +/** + * Calculate ECC discrete logarithm for small factors. + * Opposite of #GNUNET_CRYPTO_ecc_dexp(). + * + * @param edc precalculated values, determine range of factors + * @param input point on the curve to factor + * @return INT_MAX if dlog failed, otherwise the factor + */ +int +GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, + const struct GNUNET_CRYPTO_EccPoint *input); + + +/** + * Multiply the generator g of the elliptic curve by @a val + * to obtain the point on the curve representing @a val. + * Afterwards, point addition will correspond to integer + * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to + * convert a point back to an integer (as long as the + * integer is smaller than the MAX of the @a edc context). + * + * @param val value to encode into a point + * @param r where to write the point (must be allocated) + */ +void +GNUNET_CRYPTO_ecc_dexp (int val, + struct GNUNET_CRYPTO_EccPoint*r); + + +/** + * Multiply the generator g of the elliptic curve by @a val + * to obtain the point on the curve representing @a val. + * + * @param val (positive) value to encode into a point + * @param r where to write the point (must be allocated) + * @return #GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecc_dexp_mpi (const struct GNUNET_CRYPTO_EccScalar *val, + struct GNUNET_CRYPTO_EccPoint *r); + + +/** + * Multiply the point @a p on the elliptic curve by @a val. + * + * @param p point to multiply + * @param val (positive) value to encode into a point + * @param r where to write the point (must be allocated) + * @return #GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecc_pmul_mpi (const struct GNUNET_CRYPTO_EccPoint *p, + const struct GNUNET_CRYPTO_EccScalar *val, + struct GNUNET_CRYPTO_EccPoint *r); + + +/** + * Add two points on the elliptic curve. + * + * @param a some value + * @param b some value + * @param r where to write the point (must be allocated) + * @return #GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecc_add (const struct GNUNET_CRYPTO_EccPoint *a, + const struct GNUNET_CRYPTO_EccPoint *b, + struct GNUNET_CRYPTO_EccPoint *r); + + +/** + * Obtain a random point on the curve and its + * additive inverse. + * + * @param[out] r set to a random point on the curve + * @param[out] r_inv set to the additive inverse of @a r + * @return #GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccPoint *r, + struct GNUNET_CRYPTO_EccPoint *r_inv); + + +/** + * Obtain a random scalar for point multiplication on the curve and + * its additive inverse. + * + * @param[out] r set to a random scalar on the curve + * @param[out] r_neg set to the negation of @a + */ +void +GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccScalar *r, + struct GNUNET_CRYPTO_EccScalar *r_neg); + + +/** + * Generate a random value mod n. + * + * @param[out] r random value mod n. + */ +void +GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccScalar*r); + + +/** + * Release precalculated values. + * + * @param dlc dlog context + */ +void +GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *dlc); + + +/** + * Create a scalar from int value. + * + * @param val the int value + * @param[out] r where to write the salar + */ +void +GNUNET_CRYPTO_ecc_scalar_from_int (int64_t val, + struct GNUNET_CRYPTO_EccScalar *r); + + +/** + * @ingroup crypto + * Derive key material from a public and a private ECC key. + * This is X25519 DH (RFC 7748 Section 5) and corresponds to + * H(X25519(b,X25519(a,9))) where b := priv, pub := X25519(a,9), + * and a := #GNUNET_CRYPTO_ecdhe_key_create(). + * + * @param priv private key to use for the ECDH (x) + * @param pub public key to use for the ECDH (yG) + * @param key_material where to write the key material (xyG) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, + const struct GNUNET_CRYPTO_EcdhePublicKey *pub, + struct GNUNET_HashCode *key_material); + + +/** + * @ingroup crypto + * Derive key material from a ECDH public key and a private EdDSA key. + * Dual to #GNUNET_CRRYPTO_ecdh_eddsa. + * This uses the Ed25519 private seed as X25519 seed. + * As such, this also is a X25519 DH (see #GNUNET_CRYPTO_ecc_ecdh). + * NOTE: Whenever you can get away with it, use separate key pairs + * for signing and encryption (DH)! + * + * @param priv private key from EdDSA to use for the ECDH (x) + * @param pub public key to use for the ECDH (yG) + * @param key_material where to write the key material H(h(x)yG) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + const struct GNUNET_CRYPTO_EcdhePublicKey *pub, + struct GNUNET_HashCode *key_material); + +/** + * @ingroup crypto + * Decapsulate a key for a private EdDSA key. + * Dual to #GNUNET_CRRYPTO_eddsa_kem_encaps. + * + * @param priv private key from EdDSA to use for the ECDH (x) + * @param c the encapsulated key + * @param key_material where to write the key material H(h(x)yG) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_kem_decaps (const struct + GNUNET_CRYPTO_EddsaPrivateKey *priv, + const struct GNUNET_CRYPTO_EcdhePublicKey *c, + struct GNUNET_HashCode *key_material); + +/** + * @ingroup crypto + * Encapsulate key material for a EdDSA public key. + * Dual to #GNUNET_CRRYPTO_eddsa_kem_decaps. + * + * @param priv private key to use for the ECDH (y) + * @param c public key from EdDSA to use for the ECDH (X=h(x)G) + * @param key_material where to write the key material H(yX)=H(h(x)yG) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_kem_encaps (const struct GNUNET_CRYPTO_EddsaPublicKey *pub, + struct GNUNET_CRYPTO_EcdhePublicKey *c, + struct GNUNET_HashCode *key_material); + +/** + * This is the encapsulated key of our FO-KEM. + */ +struct GNUNET_CRYPTO_FoKemC +{ + /* The output of the FO-OWTF F(x) */ + struct GNUNET_HashCode y; + + /* The ephemeral public key from the DH in the KEM */ + struct GNUNET_CRYPTO_EcdhePublicKey pub; +}; + +/** + * @ingroup crypto + * Encapsulate key material using a CCA-secure KEM. + * The KEM is using a OWTF with image oracle constructed from + * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). + * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_decaps. + * + * @param pub public key to encapsulated for + * @param[out] c the encapsulation + * @param[out] key_material the encapsulated key + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_fo_kem_encaps ( + const struct GNUNET_CRYPTO_EddsaPublicKey *pub, + struct GNUNET_CRYPTO_FoKemC *c, + struct GNUNET_HashCode *key_material); + + +/** + * @ingroup crypto + * Decapsulate key material using a CCA-secure KEM. + * The KEM is using a OWTF with image oracle constructed from + * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). + * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_encaps. + * + * @param priv private key this encapsulation is for + * @param c the encapsulation + * @param[out] key_material the encapsulated key + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_fo_kem_decaps (const struct + GNUNET_CRYPTO_EddsaPrivateKey *priv, + const struct GNUNET_CRYPTO_FoKemC *c, + struct GNUNET_HashCode *key_material); + +/** + * @ingroup crypto + * Encapsulate key material using a CCA-secure KEM. + * The KEM is using a OWTF with image oracle constructed from + * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). + * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_decaps. + * + * @param pub public key to encapsulated for + * @param[out] c the encapsulation + * @param[out] key_material the encapsulated key + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_fo_kem_encaps (const struct + GNUNET_CRYPTO_EcdsaPublicKey *pub, + struct GNUNET_CRYPTO_FoKemC *c, + struct GNUNET_HashCode *key_material); + + +/** + * @ingroup crypto + * Decapsulate key material using a CCA-secure KEM. + * The KEM is using a OWTF with image oracle constructed from + * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). + * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_encaps. + * + * @param priv private key this encapsulation is for + * @param c the encapsulation + * @param[out] key_material the encapsulated key + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_fo_kem_decaps (const struct + GNUNET_CRYPTO_EcdsaPrivateKey *priv, + struct GNUNET_CRYPTO_FoKemC *c, + struct GNUNET_HashCode *key_material); + +/** + * @ingroup crypto + * Derive key material from a ECDH public key and a private ECDSA key. + * Dual to #GNUNET_CRRYPTO_ecdh_ecdsa. + * + * @param priv private key from ECDSA to use for the ECDH (x) + * @param pub public key to use for the ECDH (yG) + * @param key_material where to write the key material H(h(x)yG) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, + const struct GNUNET_CRYPTO_EcdhePublicKey *pub, + struct GNUNET_HashCode *key_material); + + +/** + * @ingroup crypto + * Derive key material from a EdDSA public key and a private ECDH key. + * Dual to #GNUNET_CRRYPTO_eddsa_ecdh. + * This converts the Edwards25519 public key @a pub to a Curve25519 + * public key before computing a X25519 DH (see #GNUNET_CRYPTO_ecc_ecdh). + * NOTE: Whenever you can get away with it, use separate key pairs + * for signing and encryption (DH)! + * + * @param priv private key to use for the ECDH (y) + * @param pub public key from EdDSA to use for the ECDH (X=h(x)G) + * @param key_material where to write the key material H(yX)=H(h(x)yG) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, + const struct GNUNET_CRYPTO_EddsaPublicKey *pub, + struct GNUNET_HashCode *key_material); + + +/** + * @ingroup crypto + * Derive key material from a EcDSA public key and a private ECDH key. + * Dual to #GNUNET_CRRYPTO_ecdsa_ecdh. + * + * @param priv private key to use for the ECDH (y) + * @param pub public key from ECDSA to use for the ECDH (X=h(x)G) + * @param key_material where to write the key material H(yX)=H(h(x)yG) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, + const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, + struct GNUNET_HashCode *key_material); + + +/** + * @ingroup crypto + * @brief EdDSA sign a given block. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. If possible, + * use #GNUNET_CRYPTO_eddsa_sign() instead of this function (only if @a validate + * is not fixed-size, you must use this function directly). + * + * @param priv private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param[out] sig where to write the signature + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_sign_ ( + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_EddsaSignature *sig); + + +/** + * @ingroup crypto + * @brief EdDSA sign a given block. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @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)); \ +} while (0) + + +/** + * @ingroup crypto + * @brief ECDSA Sign a given block. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. If possible, + * use #GNUNET_CRYPTO_ecdsa_sign() instead of this function (only if @a validate + * is not fixed-size, you must use this function directly). + * + * @param priv private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param[out] sig where to write the signature + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_sign_ ( + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_EcdsaSignature *sig); + +/** + * @brief + * + * @param priv + * @param data + * @param size + * @param sig + * @return enum GNUNET_GenericReturnValue + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_sign_raw ( + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + void *data, + size_t size, + struct GNUNET_CRYPTO_EddsaSignature *sig); + +/** + * @ingroup crypto + * @brief ECDSA sign a given block. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @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)); \ +} while (0) + +/** + * @ingroup crypto + * @brief Edx25519 sign a given block. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. If possible, + * use #GNUNET_CRYPTO_edx25519_sign() instead of this function (only if @a + * validate is not fixed-size, you must use this function directly). + * + * @param priv private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param[out] sig where to write the signature + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_edx25519_sign_ ( + const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_Edx25519Signature *sig); + + +/** + * @ingroup crypto + * @brief Edx25519 sign a given block. The resulting signature is compatible + * with EdDSA. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @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)); \ +} while (0) + + +/** + * @ingroup crypto + * @brief Verify EdDSA signature. + * + * The @a validate data is the beginning of the data of which the signature + * is to be verified. The `size` field in @a validate must correctly indicate + * the number of bytes of the data structure, including its header. If @a + * purpose does not match the purpose given in @a validate (the latter must be + * in big endian), signature verification fails. If possible, + * use #GNUNET_CRYPTO_eddsa_verify() instead of this function (only if @a validate + * is not fixed-size, you must use this function directly). + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param pub public key of the signer + * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_verify_ ( + uint32_t purpose, + const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, + const struct GNUNET_CRYPTO_EddsaSignature *sig, + const struct GNUNET_CRYPTO_EddsaPublicKey *pub); + + +/** + * @ingroup crypto + * @brief Verify EdDSA signature. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param purp purpose of the signature, must match 'ps->purpose.purpose' + * (except in host byte order) + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @param sig where to write the signature + */ +#define GNUNET_CRYPTO_eddsa_verify(purp,ps,sig,pub) ({ \ + /* 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_CRYPTO_eddsa_verify_ (purp, \ + &(ps)->purpose, \ + sig, \ + pub); \ + }) + +/** + * @ingroup crypto + * @brief Verify ECDSA signature. + * + * The @a validate data is the beginning of the data of which the signature is + * to be verified. The `size` field in @a validate must correctly indicate the + * number of bytes of the data structure, including its header. If @a purpose + * does not match the purpose given in @a validate (the latter must be in big + * endian), signature verification fails. If possible, use + * #GNUNET_CRYPTO_eddsa_verify() instead of this function (only if @a validate + * is not fixed-size, you must use this function directly). + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param pub public key of the signer + * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_verify_ ( + uint32_t purpose, + const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, + const struct GNUNET_CRYPTO_EcdsaSignature *sig, + const struct GNUNET_CRYPTO_EcdsaPublicKey *pub); + + +/** + * @ingroup crypto + * @brief Verify ECDSA signature. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param purp purpose of the signature, must match 'ps->purpose.purpose' + * (except in host byte order) + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @param sig where to write the signature + */ +#define GNUNET_CRYPTO_ecdsa_verify(purp,ps,sig,pub) ({ \ + /* 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_CRYPTO_ecdsa_verify_ (purp, \ + &(ps)->purpose, \ + sig, \ + pub); \ + }) + +/** + * @ingroup crypto + * @brief Verify Edx25519 signature. + * + * The @a validate data is the beginning of the data of which the signature + * is to be verified. The `size` field in @a validate must correctly indicate + * the number of bytes of the data structure, including its header. If @a + * purpose does not match the purpose given in @a validate (the latter must be + * in big endian), signature verification fails. If possible, use + * #GNUNET_CRYPTO_edx25519_verify() instead of this function (only if @a + * validate is not fixed-size, you must use this function directly). + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param pub public key of the signer + * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_edx25519_verify_ ( + uint32_t purpose, + const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, + const struct GNUNET_CRYPTO_Edx25519Signature *sig, + const struct GNUNET_CRYPTO_Edx25519PublicKey *pub); + + +/** + * @ingroup crypto + * @brief Verify Edx25519 signature. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param purp purpose of the signature, must match 'ps->purpose.purpose' + * (except in host byte order) + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @param sig where to write the signature + */ +#define GNUNET_CRYPTO_edx25519_verify(purp,ps,sig,pub) ({ \ + /* 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_CRYPTO_edx25519_verify_ (purp, \ + &(ps)->purpose, \ + sig, \ + pub); \ + }) + +/** + * @ingroup crypto + * Derive a private key from a given private key and a label. + * Essentially calculates a private key 'h = H(l,P) * d mod n' + * where n is the size of the ECC group and P is the public + * key associated with the private key 'd'. + * + * @param priv original private key + * @param label label to use for key deriviation + * @param context additional context to use for HKDF of 'h'; + * typically the name of the subsystem/application + * @return derived private key + */ +struct GNUNET_CRYPTO_EcdsaPrivateKey * +GNUNET_CRYPTO_ecdsa_private_key_derive ( + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, + const char *label, + const char *context); + + +/** + * @ingroup crypto + * Derive a public key from a given public key and a label. + * Essentially calculates a public key 'V = H(l,P) * P'. + * + * @param pub original public key + * @param label label to use for key deriviation + * @param context additional context to use for HKDF of 'h'. + * typically the name of the subsystem/application + * @param result where to write the derived public key + */ +void +GNUNET_CRYPTO_ecdsa_public_key_derive ( + const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, + const char *label, + const char *context, + struct GNUNET_CRYPTO_EcdsaPublicKey *result); + +/** + * This is a signature function for ECDSA which takes a + * private key, derives/blinds it and signs the message. + * + * @param pkey original private key + * @param label label to use for key deriviation + * @param context additional context to use for HKDF of 'h'; + * typically the name of the subsystem/application + * @param purpose the signature purpose + * @param sig the resulting signature + * @return GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdsa_sign_derived ( + const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const char *label, + const char *context, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_EcdsaSignature *sig); + + +/** + * @ingroup crypto + * Derive a private scalar from a given private key and a label. + * Essentially calculates a private key 'h = H(l,P) * d mod n' + * where n is the size of the ECC group and P is the public + * key associated with the private key 'd'. + * The result is the derived private _scalar_, not the private + * key as for EdDSA we cannot derive before we hash the + * private key. + * + * @param priv original private key + * @param label label to use for key deriviation + * @param context additional context to use for HKDF of 'h'; + * typically the name of the subsystem/application + * @param result derived private scalar + */ +void +GNUNET_CRYPTO_eddsa_private_key_derive ( + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + const char *label, + const char *context, + struct GNUNET_CRYPTO_EddsaPrivateScalar *result); + + +/** + * @ingroup crypto + * Derive a public key from a given public key and a label. + * Essentially calculates a public key 'V = H(l,P) * P'. + * + * @param pub original public key + * @param label label to use for key deriviation + * @param context additional context to use for HKDF of 'h'. + * typically the name of the subsystem/application + * @param result where to write the derived public key + */ +void +GNUNET_CRYPTO_eddsa_public_key_derive ( + const struct GNUNET_CRYPTO_EddsaPublicKey *pub, + const char *label, + const char *context, + struct GNUNET_CRYPTO_EddsaPublicKey *result); + + +/** + * This is a signature function for EdDSA which takes a + * private key and derives it using the label and context + * before signing. + * + * @param pkey original private key + * @param label label to use for key deriviation + * @param context additional context to use for HKDF of 'h'; + * typically the name of the subsystem/application + * @param purpose the signature purpose + * @param sig the resulting signature + * @return GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_sign_derived ( + const struct GNUNET_CRYPTO_EddsaPrivateKey *pkey, + const char *label, + const char *context, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_EddsaSignature *sig); + + +/** + * Extract the public key of the given private scalar. + * + * @param s the private scalar + * @param pkey the resulting public key + */ +void +GNUNET_CRYPTO_eddsa_key_get_public_from_scalar ( + const struct GNUNET_CRYPTO_EddsaPrivateScalar *s, + struct GNUNET_CRYPTO_EddsaPublicKey *pkey); + +/** + * @ingroup crypto + * Derive a private scalar from a given private key and a label. + * Essentially calculates a private key 'h = H(l,P) * d mod n' + * where n is the size of the ECC group and P is the public + * key associated with the private key 'd'. + * + * @param priv original private key + * @param seed input seed + * @param seedsize size of the seed + * @param result derived private key + */ +void +GNUNET_CRYPTO_edx25519_private_key_derive ( + const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, + const void *seed, + size_t seedsize, + struct GNUNET_CRYPTO_Edx25519PrivateKey *result); + + +/** + * @ingroup crypto + * Derive a public key from a given public key and a label. + * Essentially calculates a public key 'V = H(l,P) * P'. + * + * @param pub original public key + * @param seed input seed + * @param seedsize size of the seed + * @param result where to write the derived public key + */ +void +GNUNET_CRYPTO_edx25519_public_key_derive ( + const struct GNUNET_CRYPTO_Edx25519PublicKey *pub, + const void *seed, + size_t seedsize, + struct GNUNET_CRYPTO_Edx25519PublicKey *result); + + +/** + * @ingroup crypto + * Clears the most significant bit and second most significant bit of the serialized representaive before applying elligator direct map. + * + * @param representative serialized elligator representative of an element of Curves25519's finite field + * @param point destination for the calculated point on the curve + * @param high_y bool pointed to will be set to 'true' if corresponding y-coordinate is > 2 ^ 254 - 10, otherwise 0. Can be set to NULL if not needed. + */ +void +GNUNET_CRYPTO_ecdhe_elligator_decoding ( + struct GNUNET_CRYPTO_EcdhePublicKey *point, + bool *high_y, + const struct GNUNET_CRYPTO_ElligatorRepresentative *representative); + +/** + * @ingroup crypto + * Encodes a point on Curve25519 to a an element of the underlying finite field. + * This transformation is deterministic. + * + * @param r storage for the calculated representative + * @param pub a point on the curve + * @param high_y encodes if y-coordinate is > 2 ^254 - 10, which determines the representative value out of two + * @return 'true' if the given point can be encoded into a representative. Otherwise 'false' is returned and the content of the representative storage is undefined + */ +bool +GNUNET_CRYPTO_ecdhe_elligator_encoding ( + struct GNUNET_CRYPTO_ElligatorRepresentative *r, + const struct GNUNET_CRYPTO_EcdhePublicKey *pub, + bool high_y); + + +/** + * @ingroup crypto + * Generates a valid public key for elligator's inverse map by adding a lower order point to a prime order point. + * Following Method 1 in description https://elligator.org/key-exchange section Step 2: Generate a “special” public key. + * + * @param pub valid public key for elligator inverse map + * @param pk private key for generating valid public key + * @return GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_ecdhe_elligator_generate_public_key ( + struct GNUNET_CRYPTO_EcdhePublicKey *pub, + struct GNUNET_CRYPTO_EcdhePrivateKey *pk); + + +/** + * @ingroup crypto + * Generates a private key for Curve25519 and the elligator representative of the corresponding public key. + * + * @param repr representative of the public key + * @param pk Curve25519 private key + */ +void +GNUNET_CRYPTO_ecdhe_elligator_key_create ( + struct GNUNET_CRYPTO_ElligatorRepresentative *repr, + struct GNUNET_CRYPTO_EcdhePrivateKey *pk); + +/** + * @ingroup crypto + * Carries out ecdh encapsulation with given public key and the private key from a freshly created ephemeral key pair. + * Following the terminology in https://eprint.iacr.org/2021/509.pdf. + * + * @param pub given edwards curve public key (X) + * @param r representative of ephemeral public key A to use for the ECDH (direct_map(r)=A=aG) + * @param key_material where to write the key material H(aX)=H(x(aG)) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_elligator_kem_encaps ( + const struct GNUNET_CRYPTO_EddsaPublicKey *pub, + struct GNUNET_CRYPTO_ElligatorRepresentative *r, + struct GNUNET_HashCode *key_material); + +/** + * @ingroup crypto + * Carries out ecdh decapsulation with own private key and the representative of the received public key. + * Following the terminology in https://eprint.iacr.org/2021/509.pdf. + * + * @param priv own private key (x) + * @param r received representative r, from which we can obtain the public key A (direct_map(r)=A=aG) + * @param key_material where to write the key material H(xA)=H(a(xG)) + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_eddsa_elligator_kem_decaps ( + const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, + const struct GNUNET_CRYPTO_ElligatorRepresentative *r, + struct GNUNET_HashCode *key_material); + + +/** + * Output the given MPI value to the given buffer in network + * byte order. The MPI @a val may not be negative. + * + * @param buf where to output to + * @param size number of bytes in @a buf + * @param val value to write to @a buf + */ +void +GNUNET_CRYPTO_mpi_print_unsigned (void *buf, + size_t size, + gcry_mpi_t val); + + +/** + * Convert data buffer into MPI value. + * The buffer is interpreted as network + * byte order, unsigned integer. + * + * @param result where to store MPI value (allocated) + * @param data raw data (GCRYMPI_FMT_USG) + * @param size number of bytes in @a data + */ +void +GNUNET_CRYPTO_mpi_scan_unsigned (gcry_mpi_t *result, + const void *data, + size_t size); + + +/** + * Create a freshly generated paillier public key. + * + * @param[out] public_key Where to store the public key? + * @param[out] private_key Where to store the private key? + */ +void +GNUNET_CRYPTO_paillier_create ( + struct GNUNET_CRYPTO_PaillierPublicKey *public_key, + struct GNUNET_CRYPTO_PaillierPrivateKey *private_key); + + +/** + * Encrypt a plaintext with a paillier public key. + * + * @param public_key Public key to use. + * @param m Plaintext to encrypt. + * @param desired_ops How many homomorphic ops the caller intends to use + * @param[out] ciphertext Encryption of @a plaintext with @a public_key. + * @return guaranteed number of supported homomorphic operations >= 1, + * or desired_ops, in case that is lower, + * or -1 if less than one homomorphic operation is possible + */ +int +GNUNET_CRYPTO_paillier_encrypt ( + const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, + const gcry_mpi_t m, + int desired_ops, + struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext); + + +/** + * Decrypt a paillier ciphertext with a private key. + * + * @param private_key Private key to use for decryption. + * @param public_key Public key to use for decryption. + * @param ciphertext Ciphertext to decrypt. + * @param[out] m Decryption of @a ciphertext with @a private_key. + */ +void +GNUNET_CRYPTO_paillier_decrypt ( + const struct GNUNET_CRYPTO_PaillierPrivateKey *private_key, + const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, + const struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext, + gcry_mpi_t m); + + +/** + * Compute a ciphertext that represents the sum of the plaintext in @a c1 + * and @a c2 + * + * Note that this operation can only be done a finite number of times + * before an overflow occurs. + * + * @param public_key Public key to use for encryption. + * @param c1 Paillier cipher text. + * @param c2 Paillier cipher text. + * @param[out] result Result of the homomorphic operation. + * @return #GNUNET_OK if the result could be computed, + * #GNUNET_SYSERR if no more homomorphic operations are remaining. + */ +int +GNUNET_CRYPTO_paillier_hom_add ( + const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, + const struct GNUNET_CRYPTO_PaillierCiphertext *c1, + const struct GNUNET_CRYPTO_PaillierCiphertext *c2, + struct GNUNET_CRYPTO_PaillierCiphertext *result); + + +/** + * Get the number of remaining supported homomorphic operations. + * + * @param c Paillier cipher text. + * @return the number of remaining homomorphic operations + */ +int +GNUNET_CRYPTO_paillier_hom_get_remaining ( + const struct GNUNET_CRYPTO_PaillierCiphertext *c); + + +/* ********* Chaum-style RSA-based blind signatures ******************* */ + + +/** + * The private information of an RSA key pair. + */ +struct GNUNET_CRYPTO_RsaPrivateKey; + +/** + * The public information of an RSA key pair. + */ +struct GNUNET_CRYPTO_RsaPublicKey; + +/** + * Constant-size pre-secret for blinding key generation. + */ +struct GNUNET_CRYPTO_RsaBlindingKeySecret +{ + /** + * Bits used to generate the blinding key. 256 bits + * of entropy is enough. + */ + uint32_t pre_secret[8] GNUNET_PACKED; +}; + +/** + * @brief an RSA signature + */ +struct GNUNET_CRYPTO_RsaSignature; + + +/** + * Create a new private key. Caller must free return value. + * + * @param len length of the key in bits (e.g. 2048) + * @return fresh private key + */ +struct GNUNET_CRYPTO_RsaPrivateKey * +GNUNET_CRYPTO_rsa_private_key_create (unsigned int len); + + +/** + * Free memory occupied by the private key. + * + * @param key pointer to the memory to free + */ +void +GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key); + + +/** + * Encode the private key in a format suitable for + * storing it into a file. + * + * @param key the private key + * @param[out] buffer set to a buffer with the encoded key + * @return size of memory allocatedin @a buffer + */ +size_t +GNUNET_CRYPTO_rsa_private_key_encode ( + const struct GNUNET_CRYPTO_RsaPrivateKey *key, + void **buffer); + + +/** + * Decode the private key from the data-format back + * to the "normal", internal format. + * + * @param buf the buffer where the private key data is stored + * @param buf_size the size of the data in @a buf + * @return NULL on error + */ +struct GNUNET_CRYPTO_RsaPrivateKey * +GNUNET_CRYPTO_rsa_private_key_decode (const void *buf, + size_t buf_size); + + +/** + * Duplicate the given private key + * + * @param key the private key to duplicate + * @return the duplicate key; NULL upon error + */ +struct GNUNET_CRYPTO_RsaPrivateKey * +GNUNET_CRYPTO_rsa_private_key_dup ( + const struct GNUNET_CRYPTO_RsaPrivateKey *key); + + +/** + * Extract the public key of the given private key. + * + * @param priv the private key + * @return NULL on error, otherwise the public key + */ +struct GNUNET_CRYPTO_RsaPublicKey * +GNUNET_CRYPTO_rsa_private_key_get_public ( + const struct GNUNET_CRYPTO_RsaPrivateKey *priv); + + +/** + * Compute hash over the public key. + * + * @param key public key to hash + * @param hc where to store the hash code + */ +void +GNUNET_CRYPTO_rsa_public_key_hash ( + const struct GNUNET_CRYPTO_RsaPublicKey *key, + struct GNUNET_HashCode *hc); + + +/** + * Check if @a key is well-formed. + * + * @return true if @a key is well-formed. + */ +bool +GNUNET_CRYPTO_rsa_public_key_check ( + const struct GNUNET_CRYPTO_RsaPublicKey *key); + +/** + * Obtain the length of the RSA key in bits. + * + * @param key the public key to introspect + * @return length of the key in bits + */ +unsigned int +GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key); + + +/** + * Free memory occupied by the public key. + * + * @param key pointer to the memory to free + */ +void +GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key); + + +/** + * Encode the public key in a format suitable for + * storing it into a file. + * + * @param key the private key + * @param[out] buffer set to a buffer with the encoded key + * @return size of memory allocated in @a buffer + */ +size_t +GNUNET_CRYPTO_rsa_public_key_encode ( + const struct GNUNET_CRYPTO_RsaPublicKey *key, + void **buffer); + + +/** + * Decode the public key from the data-format back + * to the "normal", internal format. + * + * @param buf the buffer where the public key data is stored + * @param len the length of the data in @a buf + * @return NULL on error + */ +struct GNUNET_CRYPTO_RsaPublicKey * +GNUNET_CRYPTO_rsa_public_key_decode (const char *buf, + size_t len); + + +/** + * Duplicate the given public key + * + * @param key the public key to duplicate + * @return the duplicate key; NULL upon error + */ +struct GNUNET_CRYPTO_RsaPublicKey * +GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key); + + +/** + * Compare the values of two signatures. + * + * @param s1 one signature + * @param s2 the other signature + * @return 0 if the two are equal + */ +int +GNUNET_CRYPTO_rsa_signature_cmp (const struct GNUNET_CRYPTO_RsaSignature *s1, + const struct GNUNET_CRYPTO_RsaSignature *s2); + +/** + * Compare the values of two private keys. + * + * @param p1 one private key + * @param p2 the other private key + * @return 0 if the two are equal + */ +int +GNUNET_CRYPTO_rsa_private_key_cmp ( + const struct GNUNET_CRYPTO_RsaPrivateKey *p1, + const struct GNUNET_CRYPTO_RsaPrivateKey *p2); + + +/** + * Compare the values of two public keys. + * + * @param p1 one public key + * @param p2 the other public key + * @return 0 if the two are equal + */ +int +GNUNET_CRYPTO_rsa_public_key_cmp (const struct GNUNET_CRYPTO_RsaPublicKey *p1, + const struct GNUNET_CRYPTO_RsaPublicKey *p2); + + +/** + * @brief RSA Parameters to create blinded signature + */ +struct GNUNET_CRYPTO_RsaBlindedMessage +{ + /** + * Blinded message to be signed + * Note: is malloc()'ed! + */ + void *blinded_msg; + + /** + * Size of the @e blinded_msg to be signed. + */ + size_t blinded_msg_size; +}; + + +/** + * Blinds the given message with the given blinding key + * + * @param message the message to sign + * @param message_size number of bytes in @a message + * @param bks the blinding key + * @param pkey the public key of the signer + * @param[out] bm set to the blinded message + * @return #GNUNET_YES if successful, #GNUNET_NO if RSA key is malicious + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_rsa_blind (const void *message, + size_t message_size, + const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, + struct GNUNET_CRYPTO_RsaPublicKey *pkey, + struct GNUNET_CRYPTO_RsaBlindedMessage *bm); + + +/** + * Sign a blinded value, which must be a full domain hash of a message. + * + * @param key private key to use for the signing + * @param bm the (blinded) message to sign + * @return NULL on error, signature on success + */ +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key, + const struct + GNUNET_CRYPTO_RsaBlindedMessage *bm); + + +/** + * Create and sign a full domain hash of a message. + * + * @param key private key to use for the signing + * @param message the message to sign + * @param message_size number of bytes in @a message + * @return NULL on error, including a malicious RSA key, signature on success + */ +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key, + const void *message, + size_t message_size); + + +/** + * Free memory occupied by blinded message. Only frees contents, not + * @a bm itself. + * + * @param[in] bm memory to free + */ +void +GNUNET_CRYPTO_rsa_blinded_message_free ( + struct GNUNET_CRYPTO_RsaBlindedMessage *bm); + + +/** + * Free memory occupied by signature. + * + * @param[in] sig memory to free + */ +void +GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig); + + +/** + * Encode the given signature in a format suitable for storing it into a file. + * + * @param sig the signature + * @param[out] buffer set to a buffer with the encoded key + * @return size of memory allocated in @a buffer + */ +size_t +GNUNET_CRYPTO_rsa_signature_encode ( + const struct GNUNET_CRYPTO_RsaSignature *sig, + void **buffer); + + +/** + * Decode the signature from the data-format back to the "normal", internal + * format. + * + * @param buf the buffer where the public key data is stored + * @param buf_size the number of bytes of the data in @a buf + * @return NULL on error + */ +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_CRYPTO_rsa_signature_decode ( + const void *buf, + size_t buf_size); + + +/** + * Duplicate the given rsa signature + * + * @param sig the signature to duplicate + * @return the duplicate key; NULL upon error + */ +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_CRYPTO_rsa_signature_dup ( + const struct GNUNET_CRYPTO_RsaSignature *sig); + + +/** + * Unblind a blind-signed signature. The signature should have been generated + * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with + * #GNUNET_CRYPTO_rsa_blind(). + * + * @param sig the signature made on the blinded signature purpose + * @param bks the blinding key secret used to blind the signature purpose + * @param pkey the public key of the signer + * @return unblinded signature on success, NULL if RSA key is bad or malicious. + */ +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig, + const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, + struct GNUNET_CRYPTO_RsaPublicKey *pkey); + + +/** + * Verify whether the given hash corresponds to the given signature and the + * signature is valid with respect to the given public key. + * + * @param message the message to sign + * @param message_size number of bytes in @a message + * @param sig signature that is being validated + * @param public_key public key of the signer + * @returns #GNUNET_YES if ok, #GNUNET_NO if RSA key is malicious, #GNUNET_SYSERR if signature + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_rsa_verify (const void *message, + size_t message_size, + const struct GNUNET_CRYPTO_RsaSignature *sig, + const struct GNUNET_CRYPTO_RsaPublicKey *public_key); + + +/** + * Create a new random private key. + * + * @param[out] priv where to write the fresh private key + */ +void +GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv); + + +/** + * Extract the public key of the given private key. + * + * @param priv the private key + * @param[out] pub where to write the public key + */ +void +GNUNET_CRYPTO_cs_private_key_get_public ( + const struct GNUNET_CRYPTO_CsPrivateKey *priv, + struct GNUNET_CRYPTO_CsPublicKey *pub); + + +/** + * Derive a new secret r pair r0 and r1. + * In original papers r is generated randomly + * To provide abort-idempotency, r needs to be derived but still needs to be UNPREDICTABLE + * To ensure unpredictability a new nonce should be used when a new r needs to be derived. + * Uses HKDF internally. + * Comment: Can be done in one HKDF shot and split output. + * + * @param nonce is a random nonce + * @param seed seed to use in derivation + * @param lts is a long-term-secret in form of a private key + * @param[out] r array containing derived secrets r0 and r1 + */ +void +GNUNET_CRYPTO_cs_r_derive ( + const struct GNUNET_CRYPTO_CsSessionNonce *nonce, + const char *seed, + const struct GNUNET_CRYPTO_CsPrivateKey *lts, + struct GNUNET_CRYPTO_CsRSecret r[2]); + + +/** + * Extract the public R of the given secret r. + * + * @param r_priv the private key + * @param[out] r_pub where to write the public key + */ +void +GNUNET_CRYPTO_cs_r_get_public ( + const struct GNUNET_CRYPTO_CsRSecret *r_priv, + struct GNUNET_CRYPTO_CsRPublic *r_pub); + + +/** + * Derives new random blinding factors. + * In original papers blinding factors are generated randomly + * To provide abort-idempotency, blinding factors need to be derived but still need to be UNPREDICTABLE. + * To ensure unpredictability a new nonce has to be used. + * Uses HKDF internally. + * + * @param blind_seed is the blinding seed to derive blinding factors + * @param[out] bs array containing the two derived blinding secrets + */ +void +GNUNET_CRYPTO_cs_blinding_secrets_derive ( + const struct GNUNET_CRYPTO_CsBlindingNonce *blind_seed, + struct GNUNET_CRYPTO_CsBlindingSecret bs[2]); + + +/** + * @brief CS Parameters derived from the message + * during blinding to create blinded signature + */ +struct GNUNET_CRYPTO_CsBlindedMessage +{ + /** + * The Clause Schnorr c_0 and c_1 containing the blinded message + */ + struct GNUNET_CRYPTO_CsC c[2]; + + /** + * Nonce used in initial request. + */ + struct GNUNET_CRYPTO_CsSessionNonce nonce; + +}; + + +/** + * Pair of Public R values for Cs denominations + */ +struct GNUNET_CRYPTO_CSPublicRPairP +{ + struct GNUNET_CRYPTO_CsRPublic r_pub[2]; +}; + + +/** + * Calculate two blinded c's. + * Comment: One would be insecure due to Wagner's algorithm solving ROS + * + * @param bs array of the two blinding factor structs each containing alpha and beta + * @param r_pub array of the two signer's nonce R + * @param pub the public key of the signer + * @param msg the message to blind in preparation for signing + * @param msg_len length of message msg + * @param[out] blinded_c array of the two blinded c's + * @param[out] r_pub_blind array of the two blinded R + */ +void +GNUNET_CRYPTO_cs_calc_blinded_c ( + const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], + const struct GNUNET_CRYPTO_CsRPublic r_pub[2], + const struct GNUNET_CRYPTO_CsPublicKey *pub, + const void *msg, + size_t msg_len, + struct GNUNET_CRYPTO_CsC blinded_c[2], + struct GNUNET_CRYPTO_CSPublicRPairP *r_pub_blind); + + +/** + * The Sign Answer for Clause Blind Schnorr signature. + * The sign operation returns a parameter @param b and the signature + * scalar @param s_scalar. + */ +struct GNUNET_CRYPTO_CsBlindSignature +{ + /** + * To make ROS problem harder, the signer chooses an unpredictable b and + * only calculates signature of c_b + */ + unsigned int b; + + /** + * The blinded s scalar calculated from c_b + */ + struct GNUNET_CRYPTO_CsBlindS s_scalar; +}; + + +/** + * Sign a blinded @a c. + * This function derives b from a nonce and a longterm secret. + * In the original papers b is generated randomly. + * To provide abort-idempotency, b needs to be derived but still need to be UNPREDICTABLE. + * To ensure unpredictability a new nonce has to be used for every signature. + * HKDF is used internally for derivation. + * r0 and r1 can be derived prior by using GNUNET_CRYPTO_cs_r_derive. + * + * @param priv private key to use for the signing and as LTS in HKDF + * @param r array of the two secret inputs from the signer + * @param bm blinded message, including array of the two blinded c to sign c_b and the random nonce + * @param[out] cs_blind_sig where to write the blind signature + */ +void +GNUNET_CRYPTO_cs_sign_derive ( + const struct GNUNET_CRYPTO_CsPrivateKey *priv, + const struct GNUNET_CRYPTO_CsRSecret r[2], + const struct GNUNET_CRYPTO_CsBlindedMessage *bm, + struct GNUNET_CRYPTO_CsBlindSignature *cs_blind_sig); + + +/** + * Unblind a blind-signed signature using a c that was blinded + * + * @param blinded_signature_scalar the signature made on the blinded c + * @param bs the blinding factors used in the blinding + * @param[out] signature_scalar where to write the unblinded signature + */ +void +GNUNET_CRYPTO_cs_unblind ( + const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, + const struct GNUNET_CRYPTO_CsBlindingSecret *bs, + struct GNUNET_CRYPTO_CsS *signature_scalar); + + +/** + * Verify whether the given message corresponds to the given signature and the + * signature is valid with respect to the given public key. + * + * @param sig signature that is being validated + * @param pub public key of the signer + * @param msg is the message that should be signed by @a sig (message is used to calculate c) + * @param msg_len is the message length + * @returns #GNUNET_YES on success, #GNUNET_SYSERR if signature invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_cs_verify ( + const struct GNUNET_CRYPTO_CsSignature *sig, + const struct GNUNET_CRYPTO_CsPublicKey *pub, + const void *msg, + size_t msg_len); + + +/** + * Types of public keys used for blind signatures. + */ +enum GNUNET_CRYPTO_BlindSignatureAlgorithm +{ + + /** + * Invalid type of signature. + */ + GNUNET_CRYPTO_BSA_INVALID = 0, + + /** + * RSA blind signature. + */ + GNUNET_CRYPTO_BSA_RSA = 1, + + /** + * Clause Blind Schnorr signature. + */ + GNUNET_CRYPTO_BSA_CS = 2 +}; + + +/** + * @brief Type of (unblinded) signatures. + */ +struct GNUNET_CRYPTO_UnblindedSignature +{ + + /** + * Type of the signature. + */ + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; + + /** + * Reference counter. + */ + unsigned int rc; + + /** + * Details, depending on @e cipher. + */ + union + { + /** + * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. + */ + struct GNUNET_CRYPTO_CsSignature cs_signature; + + /** + * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. + */ + struct GNUNET_CRYPTO_RsaSignature *rsa_signature; + + } details; + +}; + + +/** + * @brief Type for *blinded* signatures. + * Must be unblinded before it becomes valid. + */ +struct GNUNET_CRYPTO_BlindedSignature +{ + + /** + * Type of the signature. + */ + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; + + /** + * Reference counter. + */ + unsigned int rc; + + /** + * Details, depending on @e cipher. + */ + union + { + /** + * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. + * At this point only the blinded s scalar is used. + * The final signature consisting of r,s is built after unblinding. + */ + struct GNUNET_CRYPTO_CsBlindSignature blinded_cs_answer; + + /** + * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. + */ + struct GNUNET_CRYPTO_RsaSignature *blinded_rsa_signature; + + } details; + +}; + + +/** + * @brief Type of public signing keys for blind signatures. + */ +struct GNUNET_CRYPTO_BlindSignPublicKey +{ + + /** + * Type of the public key. + */ + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; + + /** + * Reference counter. + */ + unsigned int rc; + + /** + * Hash of the public key. + */ + struct GNUNET_HashCode pub_key_hash; + + /** + * Details, depending on @e cipher. + */ + union + { + /** + * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. + */ + struct GNUNET_CRYPTO_CsPublicKey cs_public_key; + + /** + * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. + */ + struct GNUNET_CRYPTO_RsaPublicKey *rsa_public_key; + + } details; +}; + + +/** + * @brief Type of private signing keys for blind signing. + */ +struct GNUNET_CRYPTO_BlindSignPrivateKey +{ + + /** + * Type of the public key. + */ + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; + + /** + * Reference counter. + */ + unsigned int rc; + + /** + * Details, depending on @e cipher. + */ + union + { + /** + * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. + */ + struct GNUNET_CRYPTO_CsPrivateKey cs_private_key; + + /** + * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. + */ + struct GNUNET_CRYPTO_RsaPrivateKey *rsa_private_key; + + } details; +}; + + +/** + * @brief Blinded message ready for blind signing. + */ +struct GNUNET_CRYPTO_BlindedMessage +{ + /** + * Type of the sign blinded message + */ + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; + + /** + * Reference counter. + */ + unsigned int rc; + + /** + * Details, depending on @e cipher. + */ + union + { + /** + * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. + */ + struct GNUNET_CRYPTO_CsBlindedMessage cs_blinded_message; + + /** + * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. + */ + struct GNUNET_CRYPTO_RsaBlindedMessage rsa_blinded_message; + + } details; +}; + + +/** + * Secret r for Cs denominations + */ +struct GNUNET_CRYPTO_CSPrivateRPairP +{ + struct GNUNET_CRYPTO_CsRSecret r[2]; +}; + + +/** + * @brief Input needed for blinding a message. + */ +struct GNUNET_CRYPTO_BlindingInputValues +{ + + /** + * Type of the signature. + */ + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; + + /** + * Reference counter. + */ + unsigned int rc; + + /** + * Details, depending on @e cipher. + */ + union + { + /** + * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. + */ + struct GNUNET_CRYPTO_CSPublicRPairP cs_values; + + } details; + +}; + + +/** + * Nonce used to deterministiacally derive input values + * used in multi-round blind signature protocols. + */ +union GNUNET_CRYPTO_BlindSessionNonce +{ + /** + * Nonce used when signing with CS. + */ + struct GNUNET_CRYPTO_CsSessionNonce cs_nonce; +}; + + +/** + * Compute blinding input values for a given @a nonce and + * @a salt. + * + * @param bsign_priv private key to compute input values for + * @param nonce session nonce to derive input values from + * @param salt salt to include in derivation logic + * @return blinding input values + */ +struct GNUNET_CRYPTO_BlindingInputValues * +GNUNET_CRYPTO_get_blinding_input_values ( + const struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, + const char *salt); + + +/** + * Decrement reference counter of a @a bsign_pub, and free it if it reaches zero. + * + * @param[in] bsign_pub key to free + */ +void +GNUNET_CRYPTO_blind_sign_pub_decref ( + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub); + + +/** + * Decrement reference counter of a @a bsign_priv, and free it if it reaches zero. + * + * @param[in] bsign_priv key to free + */ +void +GNUNET_CRYPTO_blind_sign_priv_decref ( + struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv); + + +/** + * Decrement reference counter of a @a ub_sig, and free it if it reaches zero. + * + * @param[in] ub_sig signature to free + */ +void +GNUNET_CRYPTO_unblinded_sig_decref ( + struct GNUNET_CRYPTO_UnblindedSignature *ub_sig); + + +/** + * Decrement reference counter of a @a blind_sig, and free it if it reaches zero. + * + * @param[in] blind_sig signature to free + */ +void +GNUNET_CRYPTO_blinded_sig_decref ( + struct GNUNET_CRYPTO_BlindedSignature *blind_sig); + + +/** + * Decrement reference counter of a @a bm, and free it if it reaches zero. + * + * @param[in] bm blinded message to free + */ +void +GNUNET_CRYPTO_blinded_message_decref ( + struct GNUNET_CRYPTO_BlindedMessage *bm); + + +/** + * Increment reference counter of the given @a bm. + * + * @param[in,out] bm blinded message to increment reference counter for + * @return alias of @a bm with RC incremented + */ +struct GNUNET_CRYPTO_BlindedMessage * +GNUNET_CRYPTO_blinded_message_incref ( + struct GNUNET_CRYPTO_BlindedMessage *bm); + + +/** + * Increment reference counter of the given @a bi. + * + * @param[in,out] bi blinding input values to increment reference counter for + * @return alias of @a bi with RC incremented + */ +struct GNUNET_CRYPTO_BlindingInputValues * +GNUNET_CRYPTO_blinding_input_values_incref ( + struct GNUNET_CRYPTO_BlindingInputValues *bm); + + +/** + * Decrement reference counter of the given @a bi, and free it if it reaches + * zero. + * + * @param[in,out] bi blinding input values to decrement reference counter for + */ +void +GNUNET_CRYPTO_blinding_input_values_decref ( + struct GNUNET_CRYPTO_BlindingInputValues *bm); + + +/** + * Increment reference counter of the given @a bsign_pub. + * + * @param[in,out] bsign_pub public key to increment reference counter for + * @return alias of @a bsign_pub with RC incremented + */ +struct GNUNET_CRYPTO_BlindSignPublicKey * +GNUNET_CRYPTO_bsign_pub_incref ( + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub); + + +/** + * Increment reference counter of the given @a bsign_priv. + * + * @param[in,out] bsign_priv private key to increment reference counter for + * @return alias of @a bsign_priv with RC incremented + */ +struct GNUNET_CRYPTO_BlindSignPrivateKey * +GNUNET_CRYPTO_bsign_priv_incref ( + struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv); + + +/** + * Increment reference counter of the given @a ub_sig. + * + * @param[in,out] ub_sig signature to increment reference counter for + * @return alias of @a ub_sig with RC incremented + */ +struct GNUNET_CRYPTO_UnblindedSignature * +GNUNET_CRYPTO_ub_sig_incref (struct GNUNET_CRYPTO_UnblindedSignature *ub_sig); + + +/** + * Increment reference counter of the given @a blind_sig. + * + * @param[in,out] blind_sig signature to increment reference counter for + * @return alias of @a blind_sig with RC incremented + */ +struct GNUNET_CRYPTO_BlindedSignature * +GNUNET_CRYPTO_blind_sig_incref ( + struct GNUNET_CRYPTO_BlindedSignature *blind_sig); + + +/** + * Compare two denomination public keys. + * + * @param bp1 first key + * @param bp2 second key + * @return 0 if the keys are equal, otherwise -1 or 1 + */ +int +GNUNET_CRYPTO_bsign_pub_cmp ( + const struct GNUNET_CRYPTO_BlindSignPublicKey *bp1, + const struct GNUNET_CRYPTO_BlindSignPublicKey *bp2); + + +/** + * Compare two denomination signatures. + * + * @param sig1 first signature + * @param sig2 second signature + * @return 0 if the keys are equal, otherwise -1 or 1 + */ +int +GNUNET_CRYPTO_ub_sig_cmp (const struct GNUNET_CRYPTO_UnblindedSignature *sig1, + const struct GNUNET_CRYPTO_UnblindedSignature *sig2); + + +/** + * Compare two blinded denomination signatures. + * + * @param sig1 first signature + * @param sig2 second signature + * @return 0 if the keys are equal, otherwise -1 or 1 + */ +int +GNUNET_CRYPTO_blind_sig_cmp ( + const struct GNUNET_CRYPTO_BlindedSignature *sig1, + const struct GNUNET_CRYPTO_BlindedSignature *sig2); + + +/** + * Compare two blinded messages. + * + * @param bp1 first blinded message + * @param bp2 second blinded message + * @return 0 if the keys are equal, otherwise -1 or 1 + */ +int +GNUNET_CRYPTO_blinded_message_cmp ( + const struct GNUNET_CRYPTO_BlindedMessage *bp1, + const struct GNUNET_CRYPTO_BlindedMessage *bp2); + + +/** + * Initialize public-private key pair for blind signatures. + * + * For #GNUNET_CRYPTO_BSA_RSA, an additional "unsigned int" + * argument with the number of bits for 'n' (e.g. 2048) must + * be passed. + * + * @param[out] bsign_priv where to write the private key with RC 1 + * @param[out] bsign_pub where to write the public key with RC 1 + * @param cipher which type of cipher to use + * @param ... RSA key size (eg. 2048/3072/4096) + * @return #GNUNET_OK on success, #GNUNET_NO if parameterst were invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_blind_sign_keys_create ( + struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, + struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, + ...); + + +/** + * Initialize public-private key pair for blind signatures. + * + * For #GNUNET_CRYPTO_BSA_RSA, an additional "unsigned int" + * argument with the number of bits for 'n' (e.g. 2048) must + * be passed. + * + * @param[out] bsign_priv where to write the private key with RC 1 + * @param[out] bsign_pub where to write the public key with RC 1 + * @param cipher which type of cipher to use + * @param ap RSA key size (eg. 2048/3072/4096) + * @return #GNUNET_OK on success, #GNUNET_NO if parameterst were invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_blind_sign_keys_create_va ( + struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, + struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, + va_list ap); + + +/** + * @brief Type of blinding secrets. Must be exactly 32 bytes (DB). + */ +union GNUNET_CRYPTO_BlindingSecretP +{ + /** + * Clause Schnorr nonce. + */ + struct GNUNET_CRYPTO_CsBlindingNonce nonce; + + /** + * Variant for RSA for blind signatures. + */ + struct GNUNET_CRYPTO_RsaBlindingKeySecret rsa_bks; +}; + + +/** + * Blind message for blind signing with @a dk using blinding secret @a coin_bks. + * + * @param bsign_pub public key to blind for + * @param bks blinding secret to use + * @param nonce nonce used to obtain @a alg_values + * can be NULL if input values are not used for the cipher + * @param message message to sign + * @param message_size number of bytes in @a message + * @param alg_values algorithm specific values to blind the @a message + * @return blinded message to give to signer, NULL on error + */ +struct GNUNET_CRYPTO_BlindedMessage * +GNUNET_CRYPTO_message_blind_to_sign ( + const struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub, + const union GNUNET_CRYPTO_BlindingSecretP *bks, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, + const void *message, + size_t message_size, + const struct GNUNET_CRYPTO_BlindingInputValues *alg_values); + + +/** + * Create blind signature. + * + * @param bsign_priv private key to use for signing + * @param salt salt value to use for the HKDF, + * can be NULL if input values are not used for the cipher + * @param blinded_message the already blinded message to sign + * @return blind signature with RC=1, NULL on failure + */ +struct GNUNET_CRYPTO_BlindedSignature * +GNUNET_CRYPTO_blind_sign ( + const struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv, + const char *salt, + const struct GNUNET_CRYPTO_BlindedMessage *blinded_message); + + +/** + * Unblind blind signature. + * + * @param blinded_sig the blind signature + * @param bks blinding secret to use + * @param message message that was supposedly signed + * @param message_size number of bytes in @a message + * @param alg_values algorithm specific values + * @param bsign_pub public key used for signing + * @return unblinded signature with RC=1, NULL on error + */ +struct GNUNET_CRYPTO_UnblindedSignature * +GNUNET_CRYPTO_blind_sig_unblind ( + const struct GNUNET_CRYPTO_BlindedSignature *blinded_sig, + const union GNUNET_CRYPTO_BlindingSecretP *bks, + const void *message, + size_t message_size, + const struct GNUNET_CRYPTO_BlindingInputValues *alg_values, + const struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub); + + +/** + * Verify signature made blindly. + * + * @param bsign_pub public key + * @param ub_sig signature made blindly with the private key + * @param message message that was supposedly signed + * @param message_size number of bytes in @a message + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_blind_sig_verify ( + const struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub, + const struct GNUNET_CRYPTO_UnblindedSignature *ub_sig, + const void *message, + size_t message_size); + + +/** + * Get the compacted length of a #GNUNET_CRYPTO_PublicKey. + * Compacted means that it returns the minimum number of bytes this + * key is long, as opposed to the union structure inside + * #GNUNET_CRYPTO_PublicKey. + * Useful for compact serializations. + * + * @param key the key. + * @return -1 on error, else the compacted length of the key. + */ +ssize_t +GNUNET_CRYPTO_public_key_get_length (const struct + GNUNET_CRYPTO_PublicKey *key); + +/** + * Reads a #GNUNET_CRYPTO_PublicKey from a compact buffer. + * The buffer has to contain at least the compacted length of + * a #GNUNET_CRYPTO_PublicKey in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the buffer does not contain a valid key, it returns -2 as error. + * + * @param buffer the buffer + * @param len the length of buffer + * @param key the key + * @param the amount of bytes read from the buffer + * @return #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_read_public_key_from_buffer ( + const void *buffer, + size_t len, + struct GNUNET_CRYPTO_PublicKey *key, + size_t *read); + +/** + * Get the compacted length of a #GNUNET_CRYPTO_PrivateKey. + * Compacted means that it returns the minimum number of bytes this + * key is long, as opposed to the union structure inside + * #GNUNET_CRYPTO_PrivateKey. + * Useful for compact serializations. + * + * @param key the key. + * @return -1 on error, else the compacted length of the key. + */ +ssize_t +GNUNET_CRYPTO_private_key_get_length ( + const struct GNUNET_CRYPTO_PrivateKey *key); + + +/** + * Writes a #GNUNET_CRYPTO_PublicKey to a compact buffer. + * The buffer requires space for at least the compacted length of + * a #GNUNET_CRYPTO_PublicKey in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the key is not valid, it returns -2 as error. + * + * @param key the key + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes written to the buffer + */ +ssize_t +GNUNET_CRYPTO_write_public_key_to_buffer (const struct + GNUNET_CRYPTO_PublicKey *key, + void*buffer, + size_t len); + + +/** + * Reads a #GNUNET_CRYPTO_PrivateKey from a compact buffer. + * The buffer has to contain at least the compacted length of + * a #GNUNET_CRYPTO_PrivateKey in bytes. + * If the buffer is too small, the function returns GNUNET_SYSERR as error. + * + * @param buffer the buffer + * @param len the length of buffer + * @param key the key + * @param the amount of bytes read from the buffer + * @return #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_read_private_key_from_buffer ( + const void*buffer, + size_t len, + struct GNUNET_CRYPTO_PrivateKey *key, + size_t *read); + + +/** + * Writes a #GNUNET_CRYPTO_PrivateKey to a compact buffer. + * The buffer requires space for at least the compacted length of + * a #GNUNET_CRYPTO_PrivateKey in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the key is not valid, it returns -2 as error. + * + * @param key the key + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes written to the buffer + */ +ssize_t +GNUNET_CRYPTO_write_private_key_to_buffer ( + const struct GNUNET_CRYPTO_PrivateKey *key, + void*buffer, + size_t len); + + +/** + * Get the compacted length of a #GNUNET_CRYPTO_Signature. + * Compacted means that it returns the minimum number of bytes this + * signature is long, as opposed to the union structure inside + * #GNUNET_CRYPTO_Signature. + * Useful for compact serializations. + * + * @param sig the signature. + * @return -1 on error, else the compacted length of the signature. + */ +ssize_t +GNUNET_CRYPTO_signature_get_length ( + const struct GNUNET_CRYPTO_Signature *sig); + + +/** + * Get the compacted length of a signature by type. + * Compacted means that it returns the minimum number of bytes this + * signature is long, as opposed to the union structure inside + * #GNUNET_CRYPTO_Signature. + * Useful for compact serializations. + * + * @param sig the signature. + * @return -1 on error, else the compacted length of the signature. + */ +ssize_t +GNUNET_CRYPTO_signature_get_raw_length_by_type (uint32_t type); + + +/** + * Reads a #GNUNET_CRYPTO_Signature from a compact buffer. + * The buffer has to contain at least the compacted length of + * a #GNUNET_CRYPTO_Signature in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the buffer does not contain a valid key, it returns -2 as error. + * + * @param sig the signature + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes read from the buffer + */ +ssize_t +GNUNET_CRYPTO_read_signature_from_buffer ( + struct GNUNET_CRYPTO_Signature *sig, + const void*buffer, + size_t len); + + +/** + * Writes a #GNUNET_CRYPTO_Signature to a compact buffer. + * The buffer requires space for at least the compacted length of + * a #GNUNET_CRYPTO_Signature in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the key is not valid, it returns -2 as error. + * + * @param sig the signature + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes written to the buffer + */ +ssize_t +GNUNET_CRYPTO_write_signature_to_buffer ( + const struct GNUNET_CRYPTO_Signature *sig, + void*buffer, + size_t len); + + +/** + * @brief Sign a given block. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. If possible, + * use #GNUNET_CRYPTO_sign() instead of this function. + * + * @param priv private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param[out] sig where to write the signature + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_sign_ ( + const struct GNUNET_CRYPTO_PrivateKey *priv, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_Signature *sig); + +/** + * @brief Sign a given block. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * The signature payload and length depends on the key type. + * + * @param priv private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param[out] sig where to write the signature + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_sign_raw_ ( + const struct GNUNET_CRYPTO_PrivateKey *priv, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + unsigned char *sig); + + +/** + * @brief Sign a given block with #GNUNET_CRYPTO_PrivateKey. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @param[out] sig where to write the signature + */ +#define GNUNET_CRYPTO_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_sign_ (priv, \ + &(ps)->purpose, \ + sig)); \ +} while (0) + + +/** + * @brief Verify a given signature. + * + * The @a validate data is the beginning of the data of which the signature + * is to be verified. The `size` field in @a validate must correctly indicate + * the number of bytes of the data structure, including its header. If @a + * purpose does not match the purpose given in @a validate (the latter must be + * in big endian), signature verification fails. If possible, + * use #GNUNET_CRYPTO_signature_verify() instead of this function (only if @a validate + * is not fixed-size, you must use this function directly). + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param pub public key of the signer + * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_signature_verify_ ( + uint32_t purpose, + const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, + const struct GNUNET_CRYPTO_Signature *sig, + const struct GNUNET_CRYPTO_PublicKey *pub); + +/** + * @brief Verify a given signature. + * + * The @a validate data is the beginning of the data of which the signature + * is to be verified. The `size` field in @a validate must correctly indicate + * the number of bytes of the data structure, including its header. If @a + * purpose does not match the purpose given in @a validate (the latter must be + * in big endian), signature verification fails. + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param pub public key of the signer + * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_signature_verify_raw_ ( + uint32_t purpose, + const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, + const unsigned char *sig, + const struct GNUNET_CRYPTO_PublicKey *pub); + + +/** + * @brief Verify a given signature with #GNUNET_CRYPTO_PublicKey. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param purp purpose of the signature, must match 'ps->purpose.purpose' + * (except in host byte order) + * @param ps packed struct with what to sign, MUST begin with a purpose + * @param sig where to read the signature from + * @param pub public key to use for the verifying + */ +#define GNUNET_CRYPTO_signature_verify(purp,ps,sig,pub) ({ \ + /* 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_CRYPTO_signature_verify_ (purp, \ + &(ps)->purpose, \ + sig, \ + pub); \ + }) + + +/** + * Encrypt a block with #GNUNET_CRYPTO_PublicKey and derives a + * #GNUNET_CRYPTO_EcdhePublicKey which is required for decryption + * using ecdh to derive a symmetric key. + * + * @param block the block to encrypt + * @param size the size of the @a block + * @param pub public key to use for ecdh + * @param ecc where to write the ecc public key + * @param result the output parameter in which to store the encrypted result + * can be the same or overlap with @c block + * @returns the size of the encrypted block, -1 for errors. + * Due to the use of CFB and therefore an effective stream cipher, + * this size should be the same as @c len. + */ +ssize_t +GNUNET_CRYPTO_encrypt_old (const void *block, + size_t size, + const struct GNUNET_CRYPTO_PublicKey *pub, + struct GNUNET_CRYPTO_EcdhePublicKey *ecc, + void *result); + + +/** + * Decrypt a given block with #GNUNET_CRYPTO_PrivateKey and a given + * #GNUNET_CRYPTO_EcdhePublicKey using ecdh to derive a symmetric key. + * + * @param block the data to decrypt, encoded as returned by encrypt + * @param size the size of the @a block to decrypt + * @param priv private key to use for ecdh + * @param ecc the ecc public key + * @param result address to store the result at + * can be the same or overlap with @c block + * @return -1 on failure, size of decrypted block on success. + * Due to the use of CFB and therefore an effective stream cipher, + * this size should be the same as @c size. + */ +ssize_t +GNUNET_CRYPTO_decrypt_old ( + const void *block, + size_t size, + const struct GNUNET_CRYPTO_PrivateKey *priv, + const struct GNUNET_CRYPTO_EcdhePublicKey *ecc, + void *result); + +#define GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES (crypto_secretbox_MACBYTES \ + + sizeof (struct \ + GNUNET_CRYPTO_FoKemC)) + +/** + * Encrypt a block with #GNUNET_CRYPTO_PublicKey and derives a + * #GNUNET_CRYPTO_EcdhePublicKey which is required for decryption + * using ecdh to derive a symmetric key. + * + * Note that the result buffer for the ciphertext must be the length of + * the message to encrypt plus #GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES. + * + * @param block the block to encrypt + * @param size the size of the @a block + * @param pub public key to encrypt for + * @param result the output parameter in which to store the encrypted result + * can be the same or overlap with @c block + * @returns GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_encrypt (const void *block, + size_t size, + const struct GNUNET_CRYPTO_PublicKey *pub, + void *result, + size_t result_size); + + +/** + * Decrypt a given block with #GNUNET_CRYPTO_PrivateKey and a given + * #GNUNET_CRYPTO_EcdhePublicKey using ecdh to derive a symmetric key. + * + * @param block the data to decrypt, encoded as returned by encrypt + * @param size the size of the @a block to decrypt + * @param priv private key to use for ecdh + * @param result address to store the result at + * can be the same or overlap with @c block + * @returns GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_decrypt (const void *block, + size_t size, + const struct GNUNET_CRYPTO_PrivateKey *priv, + void *result, + size_t result_size); + + +/** + * Creates a (Base32) string representation of the public key. + * The resulting string encodes a compacted representation of the key. + * See also #GNUNET_CRYPTO_key_get_length. + * + * @param key the key. + * @return the string representation of the key, or NULL on error. + */ +char * +GNUNET_CRYPTO_public_key_to_string ( + const struct GNUNET_CRYPTO_PublicKey *key); + + +/** + * Creates a (Base32) string representation of the private key. + * The resulting string encodes a compacted representation of the key. + * See also #GNUNET_CRYPTO_key_get_length. + * + * @param key the key. + * @return the string representation of the key, or NULL on error. + */ +char * +GNUNET_CRYPTO_private_key_to_string ( + const struct GNUNET_CRYPTO_PrivateKey *key); + + +/** + * Parses a (Base32) string representation of the public key. + * See also #GNUNET_CRYPTO_public_key_to_string. + * + * @param str the encoded key. + * @param key where to write the key. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_public_key_from_string (const char*str, + struct GNUNET_CRYPTO_PublicKey *key); + + +/** + * Parses a (Base32) string representation of the private key. + * See also #GNUNET_CRYPTO_private_key_to_string. + * + * @param str the encoded key. + * @param key where to write the key. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_private_key_from_string (const char*str, + struct GNUNET_CRYPTO_PrivateKey *key); + + +/** + * Retrieves the public key representation of a private key. + * + * @param privkey the private key. + * @param key the public key result. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_key_get_public (const struct + GNUNET_CRYPTO_PrivateKey *privkey, + struct GNUNET_CRYPTO_PublicKey *key); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + + +/* ifndef GNUNET_CRYPTO_LIB_H */ +#endif + +/** @} */ /* end of group addition */ + +/* end of gnunet_crypto_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_disk_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_disk_lib.h @@ -0,0 +1,830 @@ +/* + 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 + */ +void +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 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 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 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 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. + * Guarantees not to block (returns GNUNET_SYSERR and sets errno to EAGAIN + * when no data can be read). + * + * @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_non_blocking (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 cfg_filename configuration file to parse + * @param option option with the dir name to purge + */ +void +GNUNET_DISK_purge_cfg_dir (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/libgnunet/lib/arm64-v8a/include/gnunet_dnsparser_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_dnsparser_lib.h @@ -0,0 +1,1074 @@ +/* + This file is part of GNUnet + Copyright (C) 2010-2014 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 + * @{ + * + * @author Philipp Toelke + * @author Christian Grothoff + * + * @file + * API for helper library to parse DNS packets. + * + * @defgroup dns-parser DNS parser library + * Helper library to parse DNS packets. + * @{ + */ +#ifndef GNUNET_DNSPARSER_LIB_H +#define GNUNET_DNSPARSER_LIB_H + +/** + * Maximum length of a label in DNS. + */ +#define GNUNET_DNSPARSER_MAX_LABEL_LENGTH 63 + +/** + * Maximum length of a name in DNS. + */ +#define GNUNET_DNSPARSER_MAX_NAME_LENGTH 253 + + +/** + * A few common DNS types. + */ +#define GNUNET_DNSPARSER_TYPE_ANY 0 +#define GNUNET_DNSPARSER_TYPE_A 1 +#define GNUNET_DNSPARSER_TYPE_NS 2 +#define GNUNET_DNSPARSER_TYPE_CNAME 5 +#define GNUNET_DNSPARSER_TYPE_SOA 6 +#define GNUNET_DNSPARSER_TYPE_PTR 12 +#define GNUNET_DNSPARSER_TYPE_MX 15 +#define GNUNET_DNSPARSER_TYPE_TXT 16 +#define GNUNET_DNSPARSER_TYPE_RP 17 +#define GNUNET_DNSPARSER_TYPE_AFSDB 18 +#define GNUNET_DNSPARSER_TYPE_SIG 24 +#define GNUNET_DNSPARSER_TYPE_KEY 25 +#define GNUNET_DNSPARSER_TYPE_AAAA 28 +#define GNUNET_DNSPARSER_TYPE_LOC 29 +#define GNUNET_DNSPARSER_TYPE_SRV 33 +#define GNUNET_DNSPARSER_TYPE_NAPTR 35 +#define GNUNET_DNSPARSER_TYPE_KX 36 +#define GNUNET_DNSPARSER_TYPE_CERT 37 +#define GNUNET_DNSPARSER_TYPE_DNAME 39 +#define GNUNET_DNSPARSER_TYPE_APL 42 +#define GNUNET_DNSPARSER_TYPE_DS 43 +#define GNUNET_DNSPARSER_TYPE_SSHFP 44 +#define GNUNET_DNSPARSER_TYPE_IPSECKEY 45 +#define GNUNET_DNSPARSER_TYPE_RRSIG 46 +#define GNUNET_DNSPARSER_TYPE_NSEC 47 +#define GNUNET_DNSPARSER_TYPE_DNSKEY 48 +#define GNUNET_DNSPARSER_TYPE_DHCID 49 +#define GNUNET_DNSPARSER_TYPE_NSEC3 50 +#define GNUNET_DNSPARSER_TYPE_NSEC3PARAM 51 +#define GNUNET_DNSPARSER_TYPE_TLSA 52 +#define GNUNET_DNSPARSER_TYPE_SMIMEA 53 +#define GNUNET_DNSPARSER_TYPE_HIP 55 +#define GNUNET_DNSPARSER_TYPE_CDS 59 +#define GNUNET_DNSPARSER_TYPE_CDNSKEY 60 +#define GNUNET_DNSPARSER_TYPE_OPENPGPKEY 61 +#define GNUNET_DNSPARSER_TYPE_TKEY 249 +#define GNUNET_DNSPARSER_TYPE_TSIG 250 +#define GNUNET_DNSPARSER_TYPE_ALL 255 +#define GNUNET_DNSPARSER_TYPE_URI 256 +#define GNUNET_DNSPARSER_TYPE_CAA 257 +#define GNUNET_DNSPARSER_TYPE_TA 32768 + +/** + * A DNS query. + */ +struct GNUNET_DNSPARSER_Query +{ + /** + * Name of the record that the query is for (0-terminated). + * In UTF-8 format. The library will convert from and to DNS-IDNA + * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an + * individual label is well-formed. If a given name is not well-formed, + * creating the DNS packet will fail. + */ + char *name; + + /** + * See GNUNET_DNSPARSER_TYPE_*. + */ + uint16_t type; + + /** + * See GNUNET_TUN_DNS_CLASS_*. + */ + uint16_t dns_traffic_class; +}; + + +/** + * Information from MX records (RFC 1035). + */ +struct GNUNET_DNSPARSER_MxRecord +{ + /** + * Preference for this entry (lower value is higher preference). + */ + uint16_t preference; + + /** + * Name of the mail server. + * In UTF-8 format. The library will convert from and to DNS-IDNA + * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an + * individual label is well-formed. If a given name is not well-formed, + * creating the DNS packet will fail. + */ + char *mxhost; +}; + + +/** + * Information from SRV records (RFC 2782). + */ +struct GNUNET_DNSPARSER_SrvRecord +{ + /** + * Hostname offering the service. + * In UTF-8 format. The library will convert from and to DNS-IDNA + * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an + * individual label is well-formed. If a given name is not well-formed, + * creating the DNS packet will fail. + */ + char *target; + + /** + * Preference for this entry (lower value is higher preference). Clients + * will contact hosts from the lowest-priority group first and fall back + * to higher priorities if the low-priority entries are unavailable. + */ + uint16_t priority; + + /** + * Relative weight for records with the same priority. Clients will use + * the hosts of the same (lowest) priority with a probability proportional + * to the weight given. + */ + uint16_t weight; + + /** + * TCP or UDP port of the service. + */ + uint16_t port; +}; + + +/** + * Information from URI records (RFC 7553). + */ +struct GNUNET_DNSPARSER_UriRecord +{ + /** + * URI of the target, + * where the URI is as specified in RFC 3986. + */ + char *target; + + /** + * Preference for this entry (lower value is higher preference). Clients + * will contact hosts from the lowest-priority group first and fall back + * to higher priorities if the low-priority entries are unavailable. + */ + uint16_t priority; + + /** + * Relative weight for records with the same priority. Clients will use + * the hosts of the same (lowest) priority with a probability proportional + * to the weight given. + */ + uint16_t weight; +}; + + +/** + * DNS CERT types as defined in RFC 4398. + */ +enum GNUNET_DNSPARSER_CertType +{ + /** + * Reserved value + */ + GNUNET_DNSPARSER_CERTTYPE_RESERVED = 0, + + /** + * An x509 PKIX certificate + */ + GNUNET_DNSPARSER_CERTTYPE_PKIX = 1, + + /** + * A SKPI certificate + */ + GNUNET_DNSPARSER_CERTTYPE_SKPI = 2, + + /** + * A PGP certificate + */ + GNUNET_DNSPARSER_CERTTYPE_PGP = 3, + + /** + * An x509 PKIX cert URL + */ + GNUNET_DNSPARSER_CERTTYPE_IPKIX = 4, + + /** + * A SKPI cert URL + */ + GNUNET_DNSPARSER_CERTTYPE_ISKPI = 5, + + /** + * A PGP cert fingerprint and URL + */ + GNUNET_DNSPARSER_CERTTYPE_IPGP = 6, + + /** + * An attribute Certificate + */ + GNUNET_DNSPARSER_CERTTYPE_ACPKIX = 7, + + /** + * An attribute cert URL + */ + GNUNET_DNSPARSER_CERTTYPE_IACKPIX = 8 +}; + + +/** + * DNSCERT algorithms as defined in http://www.iana.org/assignments/ + * dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml, under dns-sec-alg-numbers-1 + */ +enum GNUNET_DNSPARSER_CertAlgorithm +{ + /** + * No defined + */ + GNUNET_DNSPARSER_CERTALGO_UNDEFINED = 0, + + /** + * RSA/MD5 + */ + GNUNET_DNSPARSER_CERTALGO_RSAMD5 = 1, + + /** + * Diffie-Hellman + */ + GNUNET_DNSPARSER_CERTALGO_DH = 2, + + /** + * DSA/SHA1 + */ + GNUNET_DNSPARSER_CERTALGO_DSASHA = 3, + + /** + * Reserved + */ + GNUNET_DNSPARSER_CERTALGO_RSRVD4 = 4, + + /** + * RSA/SHA1 + */ + GNUNET_DNSPARSER_CERTALGO_RSASHA = 5, + + /** + * DSA/NSEC3/SHA + */ + GNUNET_DNSPARSER_CERTALGO_DSANSEC3 = 6, + + /** + * RSA/NSEC3/SHA + */ + GNUNET_DNSPARSER_CERTALGO_RSANSEC3 = 7, + + /** + * RSA/SHA256 + */ + GNUNET_DNSPARSER_CERTALGO_RSASHA256 = 8, + + /** + * Reserved + */ + GNUNET_DNSPARSER_CERTALGO_RSRVD9 = 9, + + /** + * RSA/SHA512 + */ + GNUNET_DNSPARSER_CERTALGO_RSASHA512 = 10, + + /** + * GHOST R 34.10-2001 + */ + GNUNET_DNSPARSER_CERTALGO_GOST_R34 = 12, + + /** + * ECDSA Curve P-256/SHA256 + */ + GNUNET_DNSPARSER_CERTALGO_ECDSA_P256SHA256 = 13, + + /** + * ECDSA Curve P-384/SHA384 + */ + GNUNET_DNSPARSER_CERTALGO_ECDSA_P384SHA384 = 14 +}; + + +/** + * Information from CERT records (RFC 4034). + */ +struct GNUNET_DNSPARSER_CertRecord +{ + /** + * Certificate type + */ + enum GNUNET_DNSPARSER_CertType cert_type; + + /** + * Certificate KeyTag + */ + uint16_t cert_tag; + + /** + * Algorithm + */ + enum GNUNET_DNSPARSER_CertAlgorithm algorithm; + + /** + * Number of bytes in @e certificate_data + */ + size_t certificate_size; + + /** + * Data of the certificate. + */ + char *certificate_data; +}; + + +/** + * Information from SOA records (RFC 1035). + */ +struct GNUNET_DNSPARSER_SoaRecord +{ + /** + * The domainname of the name server that was the + * original or primary source of data for this zone. + * In UTF-8 format. The library will convert from and to DNS-IDNA + * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an + * individual label is well-formed. If a given name is not well-formed, + * creating the DNS packet will fail. + */ + char *mname; + + /** + * A domainname which specifies the mailbox of the + * person responsible for this zone. + * In UTF-8 format. The library will convert from and to DNS-IDNA + * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an + * individual label is well-formed. If a given name is not well-formed, + * creating the DNS packet will fail. + */ + char *rname; + + /** + * The version number of the original copy of the zone. + */ + uint32_t serial; + + /** + * Time interval before the zone should be refreshed. + */ + uint32_t refresh; + + /** + * Time interval that should elapse before a failed refresh should + * be retried. + */ + uint32_t retry; + + /** + * Time value that specifies the upper limit on the time interval + * that can elapse before the zone is no longer authoritative. + */ + uint32_t expire; + + /** + * The bit minimum TTL field that should be exported with any RR + * from this zone. + */ + uint32_t minimum_ttl; +}; + + +/** + * Information from CAA records (RFC 6844). + * The tag is followed by the tag_len. + * The value is followed by the tag for (d - tag_len - 2) bytes + */ +struct GNUNET_DNSPARSER_CaaRecord +{ + /** + * The flags of the CAA record. + */ + uint8_t flags; + + /** + * The length of the tag. + */ + uint8_t tag_len; +}; + + +/** + * Binary record information (unparsed). + */ +struct GNUNET_DNSPARSER_RawRecord +{ + /** + * Binary record data. + */ + void *data; + + /** + * Number of bytes in data. + */ + size_t data_len; +}; + + +/** + * A DNS response record. + */ +struct GNUNET_DNSPARSER_Record +{ + /** + * Name of the record that the query is for (0-terminated). + * In UTF-8 format. The library will convert from and to DNS-IDNA + * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an + * individual label is well-formed. If a given name is not well-formed, + * creating the DNS packet will fail. + */ + char *name; + + /** + * Payload of the record (which one of these is valid depends on the 'type'). + */ + union + { + /** + * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname. + * In UTF-8 format. The library will convert from and to DNS-IDNA + * as necessary. Use #GNUNET_DNSPARSER_check_label() to test if an + * individual label is well-formed. If a given name is not well-formed, + * creating the DNS packet will fail. + */ + char *hostname; + + /** + * SOA data for SOA records. + */ + struct GNUNET_DNSPARSER_SoaRecord *soa; + + /** + * CERT data for CERT records. + */ + struct GNUNET_DNSPARSER_CertRecord *cert; + + /** + * MX data for MX records. + */ + struct GNUNET_DNSPARSER_MxRecord *mx; + + /** + * SRV data for SRV records. + */ + struct GNUNET_DNSPARSER_SrvRecord *srv; + + /** + * URI data for URI records. + */ + struct GNUNET_DNSPARSER_UriRecord *uri; + + /** + * Raw data for all other types. + */ + struct GNUNET_DNSPARSER_RawRecord raw; + } data; + + + /** + * When does the record expire? + */ + struct GNUNET_TIME_Absolute expiration_time; + + /** + * See GNUNET_DNSPARSER_TYPE_*. + */ + uint16_t type; + + /** + * See GNUNET_TUN_DNS_CLASS_*. + */ + uint16_t dns_traffic_class; +}; + + +/** + * Easy-to-process, parsed version of a DNS packet. + */ +struct GNUNET_DNSPARSER_Packet +{ + /** + * Array of all queries in the packet, must contain "num_queries" entries. + */ + struct GNUNET_DNSPARSER_Query *queries; + + /** + * Array of all answers in the packet, must contain "num_answers" entries. + */ + struct GNUNET_DNSPARSER_Record *answers; + + /** + * Array of all authority records in the packet, must contain "num_authority_records" entries. + */ + struct GNUNET_DNSPARSER_Record *authority_records; + + /** + * Array of all additional answers in the packet, must contain "num_additional_records" entries. + */ + struct GNUNET_DNSPARSER_Record *additional_records; + + /** + * Number of queries in the packet. + */ + unsigned int num_queries; + + /** + * Number of answers in the packet, should be 0 for queries. + */ + unsigned int num_answers; + + /** + * Number of authoritative answers in the packet, should be 0 for queries. + */ + unsigned int num_authority_records; + + /** + * Number of additional records in the packet, should be 0 for queries. + */ + unsigned int num_additional_records; + + /** + * Bitfield of DNS flags. + */ + struct GNUNET_TUN_DnsFlags flags; + + /** + * DNS ID (to match replies to requests). + */ + uint16_t id; +}; + + +/** + * Check if a label in UTF-8 format can be coded into valid IDNA. + * This can fail if the ASCII-conversion becomes longer than 63 characters. + * + * @param label label to check (UTF-8 string) + * @return #GNUNET_OK if the label can be converted to IDNA, + * #GNUNET_SYSERR if the label is not valid for DNS names + */ +int +GNUNET_DNSPARSER_check_label (const char *label); + + +/** + * Check if a hostname in UTF-8 format can be coded into valid IDNA. + * This can fail if a label becomes longer than 63 characters or if + * the entire name exceeds 253 characters. + * + * @param name name to check (UTF-8 string) + * @return #GNUNET_OK if the label can be converted to IDNA, + * #GNUNET_SYSERR if the label is not valid for DNS names + */ +int +GNUNET_DNSPARSER_check_name (const char *name); + + +/** + * Parse a UDP payload of a DNS packet in to a nice struct for further + * processing and manipulation. + * + * @param udp_payload wire-format of the DNS packet + * @param udp_payload_length number of bytes in @a udp_payload + * @return NULL on error, otherwise the parsed packet + */ +struct GNUNET_DNSPARSER_Packet * +GNUNET_DNSPARSER_parse (const char *udp_payload, + size_t udp_payload_length); + + +/** + * Free memory taken by a packet. + * + * @param p packet to free + */ +void +GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p); + + +/** + * Given a DNS packet @a p, generate the corresponding UDP payload. + * Note that we do not attempt to pack the strings with pointers + * as this would complicate the code and this is about being + * simple and secure, not fast, fancy and broken like bind. + * + * @param p packet to pack + * @param max maximum allowed size for the resulting UDP payload + * @param buf set to a buffer with the packed message + * @param buf_length set to the length of @a buf + * @return #GNUNET_SYSERR if @a p is invalid + * #GNUNET_NO if @a p was truncated (but there is still a result in @a buf) + * #GNUNET_OK if @a p was packed completely into @a buf + */ +int +GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p, + uint16_t max, + char **buf, + size_t *buf_length); + +/* ***************** low-level packing API ******************** */ + +/** + * Add a DNS name to the UDP packet at the given location, converting + * the name to IDNA notation as necessary. + * + * @param dst where to write the name (UDP packet) + * @param dst_len number of bytes in @a dst + * @param off pointer to offset where to write the name (increment by bytes used) + * must not be changed if there is an error + * @param name name to write + * @return #GNUNET_SYSERR if @a name is invalid + * #GNUNET_NO if @a name did not fit + * #GNUNET_OK if @a name was added to @a dst + */ +int +GNUNET_DNSPARSER_builder_add_name (char *dst, + size_t dst_len, + size_t *off, + const char *name); + + +/** + * Add a DNS query to the UDP packet at the given location. + * + * @param dst where to write the query + * @param dst_len number of bytes in @a dst + * @param off pointer to offset where to write the query (increment by bytes used) + * must not be changed if there is an error + * @param query query to write + * @return #GNUNET_SYSERR if @a query is invalid + * #GNUNET_NO if @a query did not fit + * #GNUNET_OK if @a query was added to @a dst + */ +int +GNUNET_DNSPARSER_builder_add_query (char *dst, + size_t dst_len, + size_t *off, + const struct GNUNET_DNSPARSER_Query *query); + + +/** + * Add an MX record to the UDP packet at the given location. + * + * @param dst where to write the mx record + * @param dst_len number of bytes in @a dst + * @param off pointer to offset where to write the mx information (increment by bytes used); + * can also change if there was an error + * @param mx mx information to write + * @return #GNUNET_SYSERR if @a mx is invalid + * #GNUNET_NO if @a mx did not fit + * #GNUNET_OK if @a mx was added to @a dst + */ +int +GNUNET_DNSPARSER_builder_add_mx (char *dst, + size_t dst_len, + size_t *off, + const struct GNUNET_DNSPARSER_MxRecord *mx); + + +/** + * Add an SOA record to the UDP packet at the given location. + * + * @param dst where to write the SOA record + * @param dst_len number of bytes in @a dst + * @param off pointer to offset where to write the SOA information (increment by bytes used) + * can also change if there was an error + * @param soa SOA information to write + * @return #GNUNET_SYSERR if @a soa is invalid + * #GNUNET_NO if @a soa did not fit + * #GNUNET_OK if @a soa was added to @a dst + */ +int +GNUNET_DNSPARSER_builder_add_soa (char *dst, + size_t dst_len, + size_t *off, + const struct GNUNET_DNSPARSER_SoaRecord *soa); + + +/** + * Add CERT record to the UDP packet at the given location. + * + * @param dst where to write the CERT record + * @param dst_len number of bytes in @a dst + * @param off pointer to offset where to write the CERT information (increment by bytes used) + * can also change if there was an error + * @param cert CERT information to write + * @return #GNUNET_SYSERR if @a soa is invalid + * #GNUNET_NO if @a soa did not fit + * #GNUNET_OK if @a soa was added to @a dst + */ +int +GNUNET_DNSPARSER_builder_add_cert (char *dst, + size_t dst_len, + size_t *off, + const struct + GNUNET_DNSPARSER_CertRecord *cert); + + +/** + * Add an SRV record to the UDP packet at the given location. + * + * @param dst where to write the SRV record + * @param dst_len number of bytes in @a dst + * @param off pointer to offset where to write the SRV information (increment by bytes used) + * can also change if there was an error + * @param srv SRV information to write + * @return #GNUNET_SYSERR if @a srv is invalid + * #GNUNET_NO if @a srv did not fit + * #GNUNET_OK if @a srv was added to @a dst + */ +int +GNUNET_DNSPARSER_builder_add_srv (char *dst, + size_t dst_len, + size_t *off, + const struct GNUNET_DNSPARSER_SrvRecord *srv); + + +/** + * Add an URI record to the UDP packet at the given location. + * + * @param dst where to write the URI record + * @param dst_len number of bytes in @a dst + * @param off pointer to offset where to write the URI information (increment by bytes used) + * can also change if there was an error + * @param uri URI information to write + * @return #GNUNET_SYSERR if @a uri is invalid + * #GNUNET_NO if @a uri did not fit + * #GNUNET_OK if @a uri was added to @a dst + */ +int +GNUNET_DNSPARSER_builder_add_uri (char *dst, + size_t dst_len, + size_t *off, + const struct GNUNET_DNSPARSER_UriRecord *uri); + +/* ***************** low-level parsing API ******************** */ + +/** + * Parse a DNS record entry. + * + * @param udp_payload entire UDP payload + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the record to parse in the udp_payload (to be + * incremented by the size of the record) + * @param r where to write the record information + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed + */ +int +GNUNET_DNSPARSER_parse_record (const char *udp_payload, + size_t udp_payload_length, + size_t *off, + struct GNUNET_DNSPARSER_Record *r); + + +/** + * Parse name inside of a DNS query or record. + * + * @param udp_payload entire UDP payload + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the name to parse in the udp_payload (to be + * incremented by the size of the name) + * @return name as 0-terminated C string on success, NULL if the payload is malformed + */ +char * +GNUNET_DNSPARSER_parse_name (const char *udp_payload, + size_t udp_payload_length, + size_t *off); + + +/** + * Parse a DNS query entry. + * + * @param udp_payload entire UDP payload + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the query to parse in the udp_payload (to be + * incremented by the size of the query) + * @param q where to write the query information + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed + */ +int +GNUNET_DNSPARSER_parse_query (const char *udp_payload, + size_t udp_payload_length, + size_t *off, + struct GNUNET_DNSPARSER_Query *q); + + +/** + * Parse a DNS SOA record. + * + * @param udp_payload reference to UDP packet + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the query to parse in the SOA record (to be + * incremented by the size of the record), unchanged on error + * @return the parsed SOA record, NULL on error + */ +struct GNUNET_DNSPARSER_SoaRecord * +GNUNET_DNSPARSER_parse_soa (const char *udp_payload, + size_t udp_payload_length, + size_t *off); + + +/** + * Parse a DNS CERT record. + * + * @param udp_payload reference to UDP packet + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the query to parse in the CERT record (to be + * incremented by the size of the record), unchanged on error + * @return the parsed CERT record, NULL on error + */ +struct GNUNET_DNSPARSER_CertRecord * +GNUNET_DNSPARSER_parse_cert (const char *udp_payload, + size_t udp_payload_length, + size_t *off); + + +/** + * Parse a DNS MX record. + * + * @param udp_payload reference to UDP packet + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the query to parse in the MX record (to be + * incremented by the size of the record), unchanged on error + * @return the parsed MX record, NULL on error + */ +struct GNUNET_DNSPARSER_MxRecord * +GNUNET_DNSPARSER_parse_mx (const char *udp_payload, + size_t udp_payload_length, + size_t *off); + + +/** + * Parse a DNS SRV record. + * + * @param udp_payload reference to UDP packet + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the query to parse in the SRV record (to be + * incremented by the size of the record), unchanged on error + * @return the parsed SRV record, NULL on error + */ +struct GNUNET_DNSPARSER_SrvRecord * +GNUNET_DNSPARSER_parse_srv (const char *udp_payload, + size_t udp_payload_length, + size_t *off); + + +/** + * Parse a DNS URI record. + * + * @param udp_payload reference to UDP packet + * @param udp_payload_length length of @a udp_payload + * @param off pointer to the offset of the query to parse in the URI record (to be + * incremented by the size of the record), unchanged on error + * @return the parsed URI record, NULL on error + */ +struct GNUNET_DNSPARSER_UriRecord * +GNUNET_DNSPARSER_parse_uri (const char *udp_payload, + size_t udp_payload_length, + size_t *off); + +/* ***************** low-level duplication API ******************** */ + +/** + * Duplicate (deep-copy) the given DNS record + * + * @param r the record + * @return the newly allocated record + */ +struct GNUNET_DNSPARSER_Record * +GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r); + + +/** + * Duplicate (deep-copy) the given DNS record + * + * @param r the record + * @return the newly allocated record + */ +struct GNUNET_DNSPARSER_SoaRecord * +GNUNET_DNSPARSER_duplicate_soa_record (const struct + GNUNET_DNSPARSER_SoaRecord *r); + + +/** + * Duplicate (deep-copy) the given DNS record + * + * @param r the record + * @return the newly allocated record + */ +struct GNUNET_DNSPARSER_CertRecord * +GNUNET_DNSPARSER_duplicate_cert_record (const struct + GNUNET_DNSPARSER_CertRecord *r); + + +/** + * Duplicate (deep-copy) the given DNS record + * + * @param r the record + * @return the newly allocated record + */ +struct GNUNET_DNSPARSER_MxRecord * +GNUNET_DNSPARSER_duplicate_mx_record (const struct + GNUNET_DNSPARSER_MxRecord *r); + + +/** + * Duplicate (deep-copy) the given DNS record + * + * @param r the record + * @return the newly allocated record + */ +struct GNUNET_DNSPARSER_SrvRecord * +GNUNET_DNSPARSER_duplicate_srv_record (const struct + GNUNET_DNSPARSER_SrvRecord *r); + + +/** + * Duplicate (deep-copy) the given DNS record + * + * @param r the record + * @return the newly allocated record + */ +struct GNUNET_DNSPARSER_UriRecord * +GNUNET_DNSPARSER_duplicate_uri_record (const struct + GNUNET_DNSPARSER_UriRecord *r); + +/* ***************** low-level deallocation API ******************** */ + +/** + * Free the given DNS record. + * + * @param r record to free + */ +void +GNUNET_DNSPARSER_free_record (struct GNUNET_DNSPARSER_Record *r); + + +/** + * Free MX information record. + * + * @param mx record to free + */ +void +GNUNET_DNSPARSER_free_mx (struct GNUNET_DNSPARSER_MxRecord *mx); + + +/** + * Free SRV information record. + * + * @param srv record to free + */ +void +GNUNET_DNSPARSER_free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv); + + +/** + * Free URI information record. + * + * @param uri record to free + */ +void +GNUNET_DNSPARSER_free_uri (struct GNUNET_DNSPARSER_UriRecord *uri); + + +/** + * Free SOA information record. + * + * @param soa record to free + */ +void +GNUNET_DNSPARSER_free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa); + + +/** + * Free CERT information record. + * + * @param cert record to free + */ +void +GNUNET_DNSPARSER_free_cert (struct GNUNET_DNSPARSER_CertRecord *cert); + + +/** + * Convert a block of binary data to HEX. + * + * @param data binary data to convert + * @param data_size number of bytes in @a data + * @return HEX string (lower case) + */ +char * +GNUNET_DNSPARSER_bin_to_hex (const void *data, + size_t data_size); + + +/** + * Convert a HEX string to block of binary data. + * + * @param hex HEX string to convert (may contain mixed case) + * @param data where to write result, must be + * at least `strlen(hex)/2` bytes long + * @return number of bytes written to data + */ +size_t +GNUNET_DNSPARSER_hex_to_bin (const char *hex, + void *data); + + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_dnsstub_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_dnsstub_lib.h @@ -0,0 +1,159 @@ +/* + This file is part of GNUnet + Copyright (C) 2012, 2018 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 + * @{ + * + * @author Christian Grothoff + * + * @file + * API for helper library to send DNS requests to DNS resolver + * + * @defgroup dns-stub DNS Stub library + * Helper library to send DNS requests to DNS resolver + * @{ + */ +#ifndef GNUNET_DNSSTUB_LIB_H +#define GNUNET_DNSSTUB_LIB_H + + +#include "gnunet_util_lib.h" + +/** + * Opaque handle to the stub resolver. + */ +struct GNUNET_DNSSTUB_Context; + +/** + * Opaque handle to a socket doing UDP requests. + */ +struct GNUNET_DNSSTUB_RequestSocket; + + +/** + * Start a DNS stub resolver. + * + * @param num_sockets how many sockets should we open + * in parallel for DNS queries for this stub? + * @return NULL on error + */ +struct GNUNET_DNSSTUB_Context * +GNUNET_DNSSTUB_start (unsigned int num_sockets); + + +/** + * Add nameserver for use by the DNSSTUB. We will use + * all provided nameservers for resolution (round-robin). + * + * @param ctx resolver context to modify + * @param dns_ip target IP address to use (as string) + * @return #GNUNET_OK on success + */ +int +GNUNET_DNSSTUB_add_dns_ip (struct GNUNET_DNSSTUB_Context *ctx, + const char *dns_ip); + + +/** + * Add nameserver for use by the DNSSTUB. We will use + * all provided nameservers for resolution (round-robin). + * + * @param ctx resolver context to modify + * @param sa socket address of DNS resolver to use + * @return #GNUNET_OK on success + */ +int +GNUNET_DNSSTUB_add_dns_sa (struct GNUNET_DNSSTUB_Context *ctx, + const struct sockaddr *sa); + + +/** + * How long should we try requests before timing out? + * Only effective for requests issued after this call. + * + * @param ctx resolver context to modify + * @param retry_freq how long to wait between retries + */ +void +GNUNET_DNSSTUB_set_retry (struct GNUNET_DNSSTUB_Context *ctx, + struct GNUNET_TIME_Relative retry_freq); + +/** + * Cleanup DNSSTUB resolver. + * + * @param ctx stub resolver to clean up + */ +void +GNUNET_DNSSTUB_stop (struct GNUNET_DNSSTUB_Context *ctx); + + +/** + * Function called with the result of a DNS resolution. + * Once this function is called, the resolution request + * is automatically cancelled / cleaned up. In particular, + * the function will only be called once. + * + * @param cls closure + * @param dns dns response, NULL on hard error (i.e. timeout) + * @param dns_len number of bytes in @a dns + */ +typedef void +(*GNUNET_DNSSTUB_ResultCallback)(void *cls, + const struct GNUNET_TUN_DnsHeader *dns, + size_t dns_len); + + +/** + * Perform DNS resolution using our default IP from init. + * + * @param ctx stub resolver to use + * @param request DNS request to transmit + * @param request_len number of bytes in msg + * @param rc function to call with result (once) + * @param rc_cls closure for @a rc + * @return socket used for the request, NULL on error + */ +struct GNUNET_DNSSTUB_RequestSocket * +GNUNET_DNSSTUB_resolve (struct GNUNET_DNSSTUB_Context *ctx, + const void *request, + size_t request_len, + GNUNET_DNSSTUB_ResultCallback rc, + void *rc_cls); + + +/** + * Cancel DNS resolution. + * + * @param rs resolution to cancel + */ +void +GNUNET_DNSSTUB_resolve_cancel (struct GNUNET_DNSSTUB_RequestSocket *rs); + + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_error_codes.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_error_codes.h @@ -0,0 +1,242 @@ +/* + This file is part of GNUnet + Copyright (C) 2012-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 + */ + /** + * @file include/taler_error_codes.h + * @brief GNUnet error codes, generated via https://gana.gnunet.org/ + * + * Do NOT edit this file, it is generated! + */ +#ifndef GNUNET_ERROR_CODES_H +#define GNUNET_ERROR_CODES_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include <limits.h> + + +/** + * Taler error codes. + */ +enum GNUNET_ErrorCode +{ + + + /** + * No error (success). + * Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0). + */ + GNUNET_EC_NONE = 0, + + + /** + * Unknown and unspecified error. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_UNKNOWN = 1, + + + /** + * Communication with service failed. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_SERVICE_COMMUNICATION_FAILED = 101, + + + /** + * Ego not found. + * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404). + */ + GNUNET_EC_IDENTITY_NOT_FOUND = 200, + + + /** + * Identifier already in use for another ego. + * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409). + */ + GNUNET_EC_IDENTITY_NAME_CONFLICT = 201, + + + /** + * The given ego is invalid or malformed. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_IDENTITY_INVALID = 202, + + + /** + * Unknown namestore error. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_NAMESTORE_UNKNOWN = 5000, + + + /** + * Zone iteration failed. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_NAMESTORE_ITERATION_FAILED = 5001, + + + /** + * Zone not found. + * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404). + */ + GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND = 5002, + + + /** + * Record not found. + * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404). + */ + GNUNET_EC_NAMESTORE_RECORD_NOT_FOUND = 5003, + + + /** + * Zone iteration failed. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_NAMESTORE_RECORD_DELETE_FAILED = 5004, + + + /** + * Zone does not contain any records. + * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404). + */ + GNUNET_EC_NAMESTORE_ZONE_EMPTY = 5005, + + + /** + * Failed to lookup record. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_NAMESTORE_LOOKUP_ERROR = 5006, + + + /** + * No records given. + * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400). + */ + GNUNET_EC_NAMESTORE_NO_RECORDS_GIVEN = 5007, + + + /** + * Record data invalid. + * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400). + */ + GNUNET_EC_NAMESTORE_RECORD_DATA_INVALID = 5008, + + + /** + * No label given. + * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400). + */ + GNUNET_EC_NAMESTORE_NO_LABEL_GIVEN = 5009, + + + /** + * No results given. + * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404). + */ + GNUNET_EC_NAMESTORE_NO_RESULTS = 5010, + + + /** + * Record already exists. + * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409). + */ + GNUNET_EC_NAMESTORE_RECORD_EXISTS = 5011, + + + /** + * Record size exceeds maximum limit. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_NAMESTORE_RECORD_TOO_BIG = 5012, + + + /** + * There was an error in the database backend. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_NAMESTORE_BACKEND_FAILED = 5013, + + + /** + * Failed to store the given records. + * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR (500). + */ + GNUNET_EC_NAMESTORE_STORE_FAILED = 5014, + + + /** + * Label invalid or malformed. + * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400). + */ + GNUNET_EC_NAMESTORE_LABEL_INVALID = 5015, + + +}; + + +/** + * Returns a hint for a given error code. + * + * @param ec the error code. + * @return the hint if it could be found, otherwise "<no hint found>" + */ +const char * +GNUNET_ErrorCode_get_hint (enum GNUNET_ErrorCode ec); + + +/** + * Return HTTP status for a given error code. + * + * @param ec the error code. + * @return the HTTP status code for the given @a ec, UINT_MAX if not found + */ +unsigned int +GNUNET_ErrorCode_get_http_status (enum GNUNET_ErrorCode ec); + + +/** + * Return HTTP status for a given error code that is guaranteed + * to work (no corner cases). + * + * @param ec the error code. + * @return the HTTP status code for the given @a ec, 500 if + * the @a ec is not found or is a client-side code + */ +unsigned int +GNUNET_ErrorCode_get_http_status_safe (enum GNUNET_ErrorCode ec); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_getopt_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_getopt_lib.h @@ -0,0 +1,511 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-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 libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * + * @file + * Command line parsing and --help formatting + * + * @defgroup getopt Getopt library + * Command line parsing and --help formatting + * @{ + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_GETOPT_LIB_H +#define GNUNET_GETOPT_LIB_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_configuration_lib.h" + +/** + * @brief General context for command line processors. + */ +struct GNUNET_GETOPT_CommandLineProcessorContext +{ + /** + * Name of the application + */ + const char *binaryName; + + /** + * Name of application with option summary + */ + const char *binaryOptions; + + /** + * Array with all command line options. + */ + const struct GNUNET_GETOPT_CommandLineOption *allOptions; + + /** + * Original command line + */ + char *const *argv; + + /** + * Total number of argv's. + */ + unsigned int argc; + + /** + * Current argument. + */ + unsigned int currentArgument; +}; + + +/** + * @brief Process a command line option + * + * @param ctx context for all options + * @param scls specific closure (for this processor) + * @param option long name of the option (e.g. "config" for --config) + * @param value argument, NULL if none was given + * @return #GNUNET_OK to continue processing other options, #GNUNET_SYSERR to abort + */ +typedef int (*GNUNET_GETOPT_CommandLineOptionProcessor) ( + struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, + void *scls, + const char *option, + const char *value); + + +/** + * @brief Definition of a command line option. + */ +struct GNUNET_GETOPT_CommandLineOption +{ + /** + * Short name of the option. + */ + const char shortName; + + /** + * Long name of the option (may not be NULL) + */ + const char *name; + + /** + * Name of the argument for the user in help text + */ + const char *argumentHelp; + + /** + * Help text for the option (description) + */ + const char *description; + + /** + * Is an argument required? #GNUNET_NO (includes optional) or + * #GNUNET_YES (required) + */ + int require_argument; + + /** + * Is the presence of this option mandatory? + */ + int option_mandatory; + + /** + * Is the option exclusive? + */ + int option_exclusive; + + /** + * Handler for the option. + */ + GNUNET_GETOPT_CommandLineOptionProcessor processor; + + /** + * Function to call on @e scls to clean up after processing all + * the arguments. Can be NULL. + */ + void (*cleaner) (void *cls); + + /** + * Specific closure to pass to the processor. + */ + void *scls; +}; + + +/** + * Defining the option to print the command line + * help text (-h option). + * + * @param about string with brief description of the application + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_help (const char *about); + + +/** + * Allow user to specify a `long long` with an offset to add to the current + * system time to construct the time seen by the application. Used for + * debugging / testing. + * + * @param shortName short name of the option + * @param name long name of the option + * @param[out] val set to the time specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_timetravel (char shortName, + const char *name); + + +/** + * Define the option to print the version of + * the application (-v option) + * + * @param version string with the version number + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_version (const char *version); + + +/** + * Allow user to specify log file name (-l option) + * + * @param[out] logfn set to the name of the logfile + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_logfile (char **logfn); + + +/** + * Allow user to specify a string. + * + * @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] str set to the string + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_string (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + char **str); + +/** + * Allow user to specify a filename (automatically path expanded). + * + * @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] str set to the string + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_filename (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + char **str); + + +/** + * Allow user to specify a binary value using Crockford + * Base32 encoding. + * + * @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 binary value decoded from Crockford Base32-encoded argument + * @param val_size size of @a val in bytes + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_base32_fixed_size (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + void *val, + size_t val_size); + + +/** + * Allow user to specify a binary value using Crockford + * Base32 encoding where the size of the binary value is + * automatically determined from its type. + * + * @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 binary value decoded from Crockford Base32-encoded argument; + * size is determined by type (sizeof (*val)). + */ +#define GNUNET_GETOPT_option_base32_auto(shortName, \ + name, \ + argumentHelp, \ + description, \ + val) \ + GNUNET_GETOPT_option_base32_fixed_size (shortName, \ + name, \ + argumentHelp, \ + description, \ + val, \ + sizeof(*val)) + + +/** + * Allow user to specify a flag (which internally means setting + * an integer to 1/#GNUNET_YES/#GNUNET_OK. + * + * @param shortName short name of the option + * @param name long name of the option + * @param description long help text for the option + * @param[out] val set to 1 if the option is present + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_flag (char shortName, + const char *name, + const char *description, + int *val); + + +/** + * Allow user to specify an `unsigned int`. + * + * @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 value specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_uint (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + unsigned int *val); + + +/** + * Allow user to specify an uint16_t. + * + * @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 value specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_uint16 (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + uint16_t *val); + + +/** + * Allow user to specify an `unsigned long long`. + * + * @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 value specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_ulong (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + unsigned long long *val); + + +/** + * Allow user to specify a `struct GNUNET_TIME_Relative` + * (using human-readable "fancy" time). + * + * @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 time specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_relative_time (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + struct GNUNET_TIME_Relative *val); + + +/** + * Allow user to specify a `struct GNUNET_TIME_Absolute` + * (using human-readable "fancy" time). + * + * @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 time specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_absolute_time (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + struct GNUNET_TIME_Absolute *val); + + +/** + * Allow user to specify a `struct GNUNET_TIME_Timestamp` + * (using human-readable "fancy" time). + * + * @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 time specified at the command line + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_timestamp (char shortName, + const char *name, + const char *argumentHelp, + const char *description, + struct GNUNET_TIME_Timestamp *val); + + +/** + * Increment @a val each time the option flag is given by one. + * + * @param shortName short name of the option + * @param name long name of the option + * @param description long help text for the option + * @param[out] val set to 1 if the option is present + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_increment_uint (char shortName, + const char *name, + const char *description, + unsigned int *val); + + +/** + * Define the '-L' log level option. Note that we do not check + * that the log level is valid here. + * + * @param[out] level set to the log level + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_loglevel (char **level); + + +/** + * Define the '-V' verbosity option. Using the option more + * than once increments @a level each time. + * + * @param[out] level set to the verbosity level + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_verbose (unsigned int *level); + + +/** + * Allow user to specify configuration file name (-c option) + * + * @param[out] fn set to the name of the configuration file + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_cfgfile (char **fn); + + +/** + * Make the given option mandatory. + * + * @param opt option to modify + * @return @a opt with the mandatory flag set. + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_mandatory (struct GNUNET_GETOPT_CommandLineOption opt); + + +/** + * Make the given option mutually exclusive with other options. + * + * @param opt option to modify + * @return @a opt with the exclusive flag set. + */ +struct GNUNET_GETOPT_CommandLineOption +GNUNET_GETOPT_option_exclusive (struct GNUNET_GETOPT_CommandLineOption opt); + + +/** + * Marker for the end of the list of options. + */ +#define GNUNET_GETOPT_OPTION_END \ + { \ + '\0', NULL, NULL, NULL, 0, 0, 0, NULL, NULL, NULL \ + } + + +/** + * Parse the command line. + * + * @param binaryOptions Name of application with option summary + * @param allOptions defined options and handlers + * @param argc number of arguments in @a argv + * @param argv actual arguments + * @return index into argv with first non-option + * argument, or #GNUNET_SYSERR on error + */ +int +GNUNET_GETOPT_run (const char *binaryOptions, + const struct GNUNET_GETOPT_CommandLineOption *allOptions, + unsigned int argc, + char *const *argv); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_GETOPT_LIB_H */ +#endif + +/** @} */ /* end of group getopt */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_getopt_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_helper_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_helper_lib.h @@ -0,0 +1,196 @@ +/* + This file is part of GNUnet. + Copyright (C) 2011, 2012 Christian Grothoff + + 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 Philipp Toelke + * @author Christian Grothoff + * + * @file + * API for dealing with SUID helper processes + * + * @defgroup helper Helper library + * Dealing with SUID helper processes. + * + * Provides an API for dealing with (SUID) helper processes + * that communicate via GNUNET_MessageHeaders on STDIN/STDOUT. + * + * @{ + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_HELPER_LIB_H +#define GNUNET_HELPER_LIB_H + + +#include "gnunet_mst_lib.h" + + +/** + * The handle to a helper process. + */ +struct GNUNET_HELPER_Handle; + + +/** + * Callback that will be called when the helper process dies. This is not called + * when the helper process is stopped using GNUNET_HELPER_stop() + * + * @param cls the closure from GNUNET_HELPER_start() + */ +typedef void +(*GNUNET_HELPER_ExceptionCallback) (void *cls); + + +/** + * Starts a helper and begins reading from it. The helper process is + * restarted when it dies except when it is stopped using GNUNET_HELPER_stop() + * or when the exp_cb callback is not NULL. + * + * @param with_control_pipe does the helper support the use of a control pipe for signalling? + * @param binary_name name of the binary to run + * @param binary_argv NULL-terminated list of arguments to give when starting the binary (this + * argument must not be modified by the client for + * the lifetime of the helper handle) + * @param cb function to call if we get messages from the helper + * @param exp_cb the exception callback to call. Set this to NULL if the helper + * process has to be restarted automatically when it dies/crashes + * @param cb_cls closure for the above callbacks + * @return the new Handle, NULL on error + */ +struct GNUNET_HELPER_Handle * +GNUNET_HELPER_start (int with_control_pipe, + const char *binary_name, + char *const binary_argv[], + GNUNET_MessageTokenizerCallback cb, + GNUNET_HELPER_ExceptionCallback exp_cb, + void *cb_cls); + + +/** + * Sends termination signal to the helper process. The helper process is not + * reaped; call GNUNET_HELPER_wait() for reaping the dead helper process. + * + * @param h the helper handle + * @param soft_kill if #GNUNET_YES, signals termination by closing the helper's + * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper + * @return #GNUNET_OK on success; #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, + int soft_kill); + + +/** + * Reap the helper process. This call is blocking (!). The helper process + * should either be sent a termination signal before or should be dead before + * calling this function + * + * @param h the helper handle + * @return #GNUNET_OK on success; #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h); + + +/** + * Free's the resources occupied by the helper handle + * + * @param h the helper handle to free + */ +void +GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h); + + +/** + * Kills the helper, closes the pipe, frees the handle and calls wait() on the + * helper process + * + * @param h handle to helper to stop + * @param soft_kill if #GNUNET_YES, signals termination by closing the helper's + * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper + */ +void +GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill); + + +/** + * Continuation function. + * + * @param cls closure + * @param result #GNUNET_OK on success, + * #GNUNET_NO if helper process died + * #GNUNET_SYSERR during GNUNET_HELPER_destroy + */ +typedef void +(*GNUNET_HELPER_Continuation)( + void *cls, + enum GNUNET_GenericReturnValue result); + + +/** + * Handle to cancel 'send' + */ +struct GNUNET_HELPER_SendHandle; + + +/** + * Send an message to the helper. + * + * @param h helper to send message to + * @param msg message to send + * @param can_drop can the message be dropped if there is already one in the queue? + * @param cont continuation to run once the message is out (#GNUNET_OK on success, #GNUNET_NO + * if the helper process died, #GNUNET_SYSERR during #GNUNET_HELPER_destroy). + * @param cont_cls closure for @a cont + * @return NULL if the message was dropped, + * otherwise handle to cancel @a cont (actual transmission may + * not be abortable) + */ +struct GNUNET_HELPER_SendHandle * +GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, + const struct GNUNET_MessageHeader *msg, + bool can_drop, + GNUNET_HELPER_Continuation cont, + void *cont_cls); + + +/** + * Cancel a #GNUNET_HELPER_send operation. If possible, transmitting + * the message is also aborted, but at least 'cont' won't be called. + * + * @param sh operation to cancel + */ +void +GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh); + + +#endif +/* end of include guard: GNUNET_HELPER_LIB_H */ + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_mq_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_mq_lib.h @@ -0,0 +1,1137 @@ +/* + This file is part of GNUnet. + Copyright (C) 2012-2016 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 libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Florian Dold + * @author Christian Grothoff + * + * @file + * General-purpose message queue + * + * @defgroup mq MQ library + * General-purpose message queue + * + * @see [Documentation](https://gnunet.org/message-queue-api) + * + * @{ + */ +#ifndef GNUNET_MQ_LIB_H +#define GNUNET_MQ_LIB_H + + +#include "gnunet_scheduler_lib.h" + +/** + * Allocate an envelope, with extra space allocated after the space needed + * by the message struct. + * The allocated message will already have the type and size field set. + * + * @param mvar variable to store the allocated message in; + * must have a header field; + * can be NULL + * @param esize extra space to allocate after the message + * @param type type of the message + * @return the MQ message + */ +#define GNUNET_MQ_msg_extra(mvar, esize, type) \ + GNUNET_MQ_msg_ (((struct GNUNET_MessageHeader **) &(mvar)), \ + (esize) + sizeof *(mvar), \ + (type)) + +/** + * Allocate a GNUNET_MQ_Envelope. + * The contained message will already have the type and size field set. + * + * @param mvar variable to store the allocated message in; + * must have a header field; + * can be NULL + * @param type type of the message + * @return the allocated envelope + */ +#define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra (mvar, 0, type) + + +/** + * Allocate a GNUNET_MQ_Envelope, where the message only consists of a header. + * The allocated message will already have the type and size field set. + * + * @param type type of the message + */ +#define GNUNET_MQ_msg_header(type) \ + GNUNET_MQ_msg_ (NULL, sizeof(struct GNUNET_MessageHeader), type) + + +/** + * Allocate a GNUNET_MQ_Envelope, where the message only consists of a header and extra space. + * The allocated message will already have the type and size field set. + * + * @param mh pointer that will changed to point at to the allocated message header + * @param esize extra space to allocate after the message header + * @param type type of the message + */ +#define GNUNET_MQ_msg_header_extra(mh, esize, type) \ + GNUNET_MQ_msg_ (&mh, (esize) + sizeof(struct GNUNET_MessageHeader), type \ + ) + + +/** + * Allocate a GNUNET_MQ_Envelope, and append a payload message after the given + * message struct. + * + * @param mvar pointer to a message struct, will be changed to point at the newly allocated message, + * whose size is 'sizeof(*mvar) + ntohs (mh->size)' + * @param type message type of the allocated message, has no effect on the nested message + * @param mh message to nest + * @return a newly allocated 'struct GNUNET_MQ_Envelope *' + */ +#define GNUNET_MQ_msg_nested_mh(mvar, type, mh) \ + ({ \ + struct GNUNET_MQ_Envelope *_ev; \ + _ev = GNUNET_MQ_msg_nested_mh_ ((struct GNUNET_MessageHeader **) &(mvar), \ + sizeof(*(mvar)), \ + (type), \ + (mh)); \ + (void) (mvar)->header; /* type check */ \ + _ev; \ + }) + + +/** + * Return a pointer to the message at the end of the given message. + * + * @param var pointer to a message struct, the type of the expression determines the base size, + * the space after the base size is the nested message + * @return a 'struct GNUNET_MessageHeader *' that points at the nested message of the given message, + * or NULL if the given message in @a var does not have any space after the message struct + */ +#define GNUNET_MQ_extract_nested_mh(var) \ + GNUNET_MQ_extract_nested_mh_ ((struct GNUNET_MessageHeader *) (var), \ + sizeof(*(var))) + + +/** + * Implementation of the #GNUNET_MQ_extract_nexted_mh macro. + * + * @param mh message header to extract nested message header from + * @param base_size size of the message before the nested message's header appears + * @return pointer to the nested message, does not copy the message + * OR NULL in case of a malformed message. + */ +const struct GNUNET_MessageHeader * +GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh, + uint16_t base_size); + + +/** + * Opaque handle to an envelope. + */ +struct GNUNET_MQ_Envelope; + + +/** + * Obtain message contained in envelope. + * + * @param env the envelope + * @return message contained in the envelope + */ +const struct GNUNET_MessageHeader * +GNUNET_MQ_env_get_msg (const struct GNUNET_MQ_Envelope *env); + + +/** + * Return next envelope in queue. + * + * @param env a queued envelope + * @return next one, or NULL + */ +const struct GNUNET_MQ_Envelope * +GNUNET_MQ_env_next (const struct GNUNET_MQ_Envelope *env); + + +/** + * Implementation of the #GNUNET_MQ_msg_nested_mh macro. + * + * @param mhp pointer to the message header pointer that will be changed to allocate at + * the newly allocated space for the message. + * @param base_size size of the data before the nested message + * @param type type of the message in the envelope + * @param nested_mh the message to append to the message after base_size + */ +struct GNUNET_MQ_Envelope * +GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp, + uint16_t base_size, + uint16_t type, + const struct GNUNET_MessageHeader *nested_mh); + + +/** + * Opaque handle to a message queue. + */ +struct GNUNET_MQ_Handle; + + +/** + * Error codes for the queue. + */ +enum GNUNET_MQ_Error +{ + /** + * Failed to read message from the network. + * FIXME: Likely not properly distinguished + * from TIMEOUT case in the code! + */ + GNUNET_MQ_ERROR_READ = 1, + + /** + * FIXME: document! + */ + GNUNET_MQ_ERROR_WRITE = 2, + + /** + * FIXME: document! + */ + GNUNET_MQ_ERROR_TIMEOUT = 4, + + /** + * We received a message that was malformed and thus + * could not be passed to its handler. + */ + GNUNET_MQ_ERROR_MALFORMED = 8, + + /** + * We received a message for which we have no matching + * handler. + */ + GNUNET_MQ_ERROR_NO_MATCH = 16 +}; + + +/** + * Per envelope preferences and priorities. + */ +enum GNUNET_MQ_PriorityPreferences +{ + /** + * Lowest priority, i.e. background traffic (e.g. NSE, FS). + * This is the default! + */ + GNUNET_MQ_PRIO_BACKGROUND = 0, + + /** + * Best-effort traffic (e.g. CADET relay, DHT) + */ + GNUNET_MQ_PRIO_BEST_EFFORT = 1, + + /** + * Urgent traffic (local peer, e.g. Conversation). + */ + GNUNET_MQ_PRIO_URGENT = 2, + + /** + * Highest priority, control traffic (e.g. CORE/CADET KX). + */ + GNUNET_MQ_PRIO_CRITICAL_CONTROL = 3, + + /** + * Bit mask to apply to extract the priority bits. + */ + GNUNET_MQ_PRIORITY_MASK = 3, + + /** + * Flag to indicate that unreliable delivery is acceptable. This + * means TRANSPORT will not attempt to receive an + * acknowledgment. CORE will just pass this flag through. CADET + * will use unreliable delivery if this flag is set. + * + * Note that even without this flag, messages may be lost by + * TRANSPORT and CORE. + * + * Thus, how "strong" the semantics of reliable delivery are depends + * on the layer! + */ + GNUNET_MQ_PREF_UNRELIABLE = 16, + + /** + * Flag to indicate that low latency is important. This flag must + * generally not be used in combination with + * #GNUNET_MQ_PREF_CORKING_ALLOWED as it would be a contradiction. + * When this flags is set, the envelope may skip forward in the + * queue (depending on priority) and also TRANSPORT should attempt + * to pick a communicator with particularly low latency. + */ + GNUNET_MQ_PREF_LOW_LATENCY = 32, + + /** + * Flag to indicate that CORKing is acceptable. This allows the + * receiver to delay transmission in hope of combining this message + * with other messages into a larger transmission with less + * per-message overhead. + */ + GNUNET_MQ_PREF_CORK_ALLOWED = 64, + + /** + * Flag to indicate that high bandwidth is desired. This flag + * indicates that the method chosen for transmission should focus on + * overall goodput. It rarely makes sense to combine this flag with + * #GNUNET_MQ_PREF_LOW_LATENCY. + */ + GNUNET_MQ_PREF_GOODPUT = 128, + + /** + * Flag to indicate that out-of-order delivery is OK. + */ + GNUNET_MQ_PREF_OUT_OF_ORDER = 256, +}; + + +/** + * Called when a message has been received. + * + * @param cls closure + * @param msg the received message + */ +typedef void +(*GNUNET_MQ_MessageCallback) ( + void *cls, + const struct GNUNET_MessageHeader *msg); + + +/** + * Called when a message needs to be validated. + * + * @param cls closure + * @param msg the received message + * @return #GNUNET_OK if the message is well-formed, + * #GNUNET_SYSERR if not + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_MQ_MessageValidationCallback) ( + void *cls, + const struct GNUNET_MessageHeader *msg); + + +/** + * Signature of functions implementing the + * sending functionality of a message queue. + * + * @param mq the message queue + * @param msg the message to send + * @param impl_state state of the implementation + */ +typedef void +(*GNUNET_MQ_SendImpl) (struct GNUNET_MQ_Handle *mq, + const struct GNUNET_MessageHeader *msg, + void *impl_state); + + +/** + * Signature of functions implementing the + * destruction of a message queue. + * Implementations must not free @a mq, but should + * take care of @a impl_state. + * + * @param mq the message queue to destroy + * @param impl_state state of the implementation + */ +typedef void +(*GNUNET_MQ_DestroyImpl) (struct GNUNET_MQ_Handle *mq, + void *impl_state); + + +/** + * Implementation function that cancels the currently sent message. + * + * @param mq message queue + * @param impl_state state specific to the implementation + */ +typedef void +(*GNUNET_MQ_CancelImpl) (struct GNUNET_MQ_Handle *mq, + void *impl_state); + + +/** + * Generic error handler, called with the appropriate + * error code and the same closure specified at the creation of + * the message queue. + * Not every message queue implementation supports an error handler. + * + * @param cls closure + * @param error error code + */ +typedef void +(*GNUNET_MQ_ErrorHandler) (void *cls, + enum GNUNET_MQ_Error error); + + +/** + * Insert @a env into the envelope DLL starting at @a env_head + * Note that @a env must not be in any MQ while this function + * is used with DLLs defined outside of the MQ module. This + * is just in case some application needs to also manage a + * FIFO of envelopes independent of MQ itself and wants to + * re-use the pointers internal to @a env. Use with caution. + * + * @param[in,out] env_head of envelope DLL + * @param[in,out] env_tail tail of envelope DLL + * @param[in,out] env element to insert at the tail + */ +void +GNUNET_MQ_dll_insert_head (struct GNUNET_MQ_Envelope **env_head, + struct GNUNET_MQ_Envelope **env_tail, + struct GNUNET_MQ_Envelope *env); + + +/** + * Insert @a env into the envelope DLL starting at @a env_head + * Note that @a env must not be in any MQ while this function + * is used with DLLs defined outside of the MQ module. This + * is just in case some application needs to also manage a + * FIFO of envelopes independent of MQ itself and wants to + * re-use the pointers internal to @a env. Use with caution. + * + * @param[in,out] env_head of envelope DLL + * @param[in,out] env_tail tail of envelope DLL + * @param[in,out] env element to insert at the tail + */ +void +GNUNET_MQ_dll_insert_tail (struct GNUNET_MQ_Envelope **env_head, + struct GNUNET_MQ_Envelope **env_tail, + struct GNUNET_MQ_Envelope *env); + + +/** + * Remove @a env from the envelope DLL starting at @a env_head. + * Note that @a env must not be in any MQ while this function + * is used with DLLs defined outside of the MQ module. This + * is just in case some application needs to also manage a + * FIFO of envelopes independent of MQ itself and wants to + * re-use the pointers internal to @a env. Use with caution. + * + * @param[in,out] env_head of envelope DLL + * @param[in,out] env_tail tail of envelope DLL + * @param[in,out] env element to remove from the DLL + */ +void +GNUNET_MQ_dll_remove (struct GNUNET_MQ_Envelope **env_head, + struct GNUNET_MQ_Envelope **env_tail, + struct GNUNET_MQ_Envelope *env); + + +/** + * Copy an array of handlers. + * + * Useful if the array has been declared in local memory and needs to be + * persisted for future use. + * + * @param handlers Array of handlers to be copied. + * @return A newly allocated array of handlers. + * Needs to be freed with #GNUNET_free. + */ +struct GNUNET_MQ_MessageHandler * +GNUNET_MQ_copy_handlers (const struct GNUNET_MQ_MessageHandler *handlers); + + +/** + * Copy an array of handlers, appending AGPL handler. + * + * Useful if the array has been declared in local memory and needs to be + * persisted for future use. + * + * @param handlers Array of handlers to be copied. Can be NULL (nothing done). + * @param agpl_handler function to call for AGPL handling + * @param agpl_cls closure for @a agpl_handler + * @return A newly allocated array of handlers. + * Needs to be freed with #GNUNET_free. + */ +struct GNUNET_MQ_MessageHandler * +GNUNET_MQ_copy_handlers2 (const struct GNUNET_MQ_MessageHandler *handlers, + GNUNET_MQ_MessageCallback agpl_handler, + void *agpl_cls); + + +/** + * Count the handlers in a handler array. + * + * @param handlers Array of handlers to be counted. + * @return The number of handlers in the array. + */ +unsigned int +GNUNET_MQ_count_handlers (const struct GNUNET_MQ_MessageHandler *handlers); + + +/** + * Message handler for a specific message type. + */ +struct GNUNET_MQ_MessageHandler +{ + /** + * Callback to validate a message of the specified @e type. + * The closure given to @e mv will be this struct (not @e ctx). + * Using NULL means only size-validation using + * @e expected_size. In this case, @e expected_size must + * be non-zero. + */ + GNUNET_MQ_MessageValidationCallback mv; + + /** + * Callback, called every time a new message of + * the specified @e type has been received. + * The closure given to @e mv will be this struct (not @e ctx). + */ + GNUNET_MQ_MessageCallback cb; + + /** + * Closure for @e mv and @e cb. + */ + void *cls; + + /** + * Type of the message this handler covers, in host byte order. + */ + uint16_t type; + + /** + * Expected size of messages of this type. Minimum size of the + * message if @e mv is non-NULL. Messages of the given type will be + * discarded (and the connection closed with an error reported to + * the application) if they do not have the right size. + */ + uint16_t expected_size; +}; + + +/** + * End-marker for the handlers array + */ +#define GNUNET_MQ_handler_end() \ + { \ + NULL, NULL, NULL, 0, 0 \ + } + + +/** + * Defines a static function @a name which takes as a single argument + * a message handler for fixed-sized messages of type @a code and with + * a message type argument of @a str. Given such an argument, the + * function @name will return a `struct GNUNET_MQ_MessageHandler` + * for the given message type. + * + * The macro is to be used as follows: + * <code> + * struct GNUNET_MessageTest { ... }; // must be fixed size + * static void + * handle_test_message (void *cls, + * const struct GNUNET_MessageTest *msg) + * { ... } + * + * struct GNUNET_MQ_MessageHandler handlers[] = { + * GNUNET_MQ_hd_fixed_size(test_message, + * GNUNET_MESSAGE_TYPE_TEST, + * struct GNUNET_MessageTest, + * "context"), + * GNUNET_MQ_handler_end() + * }; + * + * @param name unique basename for the functions + * @param code message type constant + * @param str type of the message (a struct) + * @param ctx context for the callbacks + */ +#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx) \ + ({ \ + void (*_cb)(void *cls, const str *msg) = &handle_ ## name; \ + ((struct GNUNET_MQ_MessageHandler){ NULL, \ + (GNUNET_MQ_MessageCallback) _cb, \ + (ctx), \ + (code), \ + sizeof(str) }); \ + }) + + +/** + * Defines a static function @a name which takes two arguments and a + * context-pointer for validating and handling variable-sized messages + * of type @a code and with a message type argument of @a str. Given + * such arguments, the function @name will return a `struct + * GNUNET_MQ_MessageHandler` for the given message type. + * + * The macro is to be used as follows: + * <code> + * struct GNUNET_MessageTest { ... }; // can be variable size + * static int + * check_test (void *cls, + * const struct GNUNET_MessageTest *msg) + * { + * const char *ctx = cls; + * GNUNET_assert (0 == strcmp ("context", ctx)); + * // ... + * } + * static void + * handle_test (void *cls, + * const struct GNUNET_MessageTest *msg) + * { + * const char *ctx = cls; + * GNUNET_assert (0 == strcmp ("context", ctx)); + * // ... + * } + * + * struct GNUNET_MQ_MessageHandler handlers[] = { + * GNUNET_MQ_hd_var_size(test_message, + * GNUNET_MESSAGE_TYPE_TEST, + * struct GNUNET_MessageTest, + * "context"), + * GNUNET_MQ_handler_end() + * }; + * </code> + * + * @param name unique basename for the functions + * @param code message type constant + * @param str type of the message (a struct) + * @param ctx context for the callbacks + */ +#define GNUNET_MQ_hd_var_size(name, code, str, ctx) \ + __extension__ ({ \ + int (*_mv)(void *cls, const str *msg) = &check_ ## name; \ + void (*_cb)(void *cls, const str *msg) = &handle_ ## name; \ + ((struct GNUNET_MQ_MessageHandler){ (GNUNET_MQ_MessageValidationCallback) \ + _mv, \ + (GNUNET_MQ_MessageCallback) _cb, \ + (ctx), \ + (code), \ + sizeof(str) }); \ + }) + + +/** + * Insert code for a "check_" function that verifies that + * a given variable-length message received over the network + * is followed by a 0-terminated string. If the message @a m + * is not followed by a 0-terminated string, an error is logged + * and the function is returned with #GNUNET_NO. + * + * @param an IPC message with proper type to determine + * the size, starting with a `struct GNUNET_MessageHeader` + */ +#define GNUNET_MQ_check_zero_termination(m) \ + { \ + const char *str = (const char *) &m[1]; \ + const struct GNUNET_MessageHeader *hdr = \ + (const struct GNUNET_MessageHeader *) m; \ + uint16_t slen = ntohs (hdr->size) - sizeof(*m); \ + if ((0 == slen) || (memchr (str, 0, slen) != &str[slen - 1])) \ + { \ + GNUNET_break (0); \ + return GNUNET_NO; \ + } \ + } + + +/** + * Insert code for a "check_" function that verifies that + * a given variable-length message received over the network + * is followed by another variable-length message that fits + * exactly with the given size. If the message @a m + * is not followed by another `struct GNUNET_MessageHeader` + * with a size that adds up to the total size, an error is logged + * and the function is returned with #GNUNET_NO. + * + * @param an IPC message with proper type to determine + * the size, starting with a `struct GNUNET_MessageHeader` + */ +#define GNUNET_MQ_check_boxed_message(m) \ + { \ + const struct GNUNET_MessageHeader *inbox = \ + (const struct GNUNET_MessageHeader *) &m[1]; \ + const struct GNUNET_MessageHeader *hdr = \ + (const struct GNUNET_MessageHeader *) m; \ + uint16_t slen = ntohs (hdr->size) - sizeof(*m); \ + if ((slen < sizeof(struct GNUNET_MessageHeader)) || \ + (slen != ntohs (inbox->size))) \ + { \ + GNUNET_break (0); \ + return GNUNET_NO; \ + } \ + } + + +/** + * Call the message message handler that was registered + * for the type of the given message in the given @a handlers list. + * + * This function is indented to be used for the implementation + * of message queues. + * + * @param handlers a set of handlers + * @param mh message to dispatch + * @return #GNUNET_OK on success, #GNUNET_NO if no handler matched, + * #GNUNET_SYSERR if message was rejected by check function + */ +enum GNUNET_GenericReturnValue +GNUNET_MQ_handle_message (const struct GNUNET_MQ_MessageHandler *handlers, + const struct GNUNET_MessageHeader *mh); + + +/** + * Create a new envelope. + * + * @param mhp message header to store the allocated message header in, can be NULL + * @param size size of the message to allocate + * @param type type of the message, will be set in the allocated message + * @return the allocated MQ message + */ +struct GNUNET_MQ_Envelope * +GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, + uint16_t size, + uint16_t type); + + +/** + * Create a new envelope by copying an existing message. + * + * @param hdr header of the message to copy + * @return envelope containing @a hdr + */ +struct GNUNET_MQ_Envelope * +GNUNET_MQ_msg_copy (const struct GNUNET_MessageHeader *hdr); + + +/** + * Discard the message queue message, free all + * allocated resources. Must be called in the event + * that a message is created but should not actually be sent. + * + * @param mqm the message to discard + */ +void +GNUNET_MQ_discard (struct GNUNET_MQ_Envelope *mqm); + + +/** + * Function to obtain the current envelope + * from within #GNUNET_MQ_SendImpl implementations. + * + * @param mq message queue to interrogate + * @return the current envelope + */ +struct GNUNET_MQ_Envelope * +GNUNET_MQ_get_current_envelope (struct GNUNET_MQ_Handle *mq); + + +/** + * Function to copy an envelope. The envelope must not yet + * be in any queue or have any options or callbacks set. + * + * @param env envelope to copy + * @return copy of @a env + */ +struct GNUNET_MQ_Envelope * +GNUNET_MQ_env_copy (struct GNUNET_MQ_Envelope *env); + + +/** + * Function to obtain the last envelope in the queue. + * + * @param mq message queue to interrogate + * @return the last envelope in the queue + */ +struct GNUNET_MQ_Envelope * +GNUNET_MQ_get_last_envelope (struct GNUNET_MQ_Handle *mq); + + +/** + * Set application-specific options for this envelope. + * Overrides the options set for the queue with + * #GNUNET_MQ_set_options() for this message only. + * + * @param env message to set options for + * @param pp priority and preferences to set for @a env + */ +void +GNUNET_MQ_env_set_options (struct GNUNET_MQ_Envelope *env, + enum GNUNET_MQ_PriorityPreferences pp); + + +/** + * Get performance preferences set for this envelope. + * + * @param env message to set options for + * @return priority and preferences to use + */ +enum GNUNET_MQ_PriorityPreferences +GNUNET_MQ_env_get_options (struct GNUNET_MQ_Envelope *env); + + +/** + * Combine performance preferences set for different + * envelopes that are being combined into one larger envelope. + * + * @param p1 one set of preferences + * @param p2 second set of preferences + * @return combined priority and preferences to use + */ +enum GNUNET_MQ_PriorityPreferences +GNUNET_MQ_env_combine_options (enum GNUNET_MQ_PriorityPreferences p1, + enum GNUNET_MQ_PriorityPreferences p2); + + +/** + * Remove the first envelope that has not yet been sent from the message + * queue and return it. + * + * @param mq queue to remove envelope from + * @return NULL if queue is empty (or has no envelope that is not under transmission) + */ +struct GNUNET_MQ_Envelope * +GNUNET_MQ_unsent_head (struct GNUNET_MQ_Handle *mq); + + +/** + * Set application-specific options for this queue. + * + * @param mq message queue to set options for + * @param pp priority and preferences to use by default + */ +void +GNUNET_MQ_set_options (struct GNUNET_MQ_Handle *mq, + enum GNUNET_MQ_PriorityPreferences pp); + + +/** + * Obtain the current length of the message queue. + * + * @param mq queue to inspect + * @return number of queued, non-transmitted messages + */ +unsigned int +GNUNET_MQ_get_length (struct GNUNET_MQ_Handle *mq); + + +/** + * Send a message with the given message queue. + * May only be called once per message. + * + * @param mq message queue + * @param ev the envelope with the message to send. + */ +void +GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, + struct GNUNET_MQ_Envelope *ev); + + +/** + * Send a copy of a message with the given message queue. + * Can be called repeatedly on the same envelope. + * + * @param mq message queue + * @param ev the envelope with the message to send. + */ +void +GNUNET_MQ_send_copy (struct GNUNET_MQ_Handle *mq, + const struct GNUNET_MQ_Envelope *ev); + + +/** + * Cancel sending the message. Message must have been sent with + * #GNUNET_MQ_send before. May not be called after the notify sent + * callback has been called + * + * @param ev queued envelope to cancel + */ +void +GNUNET_MQ_send_cancel (struct GNUNET_MQ_Envelope *ev); + + +/** + * Associate the assoc_data in @a mq with a unique request id. + * + * @param mq message queue, id will be unique for the queue + * @param assoc_data to associate + */ +uint32_t +GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq, + void *assoc_data); + + +/** + * Get the data associated with a @a request_id in a queue + * + * @param mq the message queue with the association + * @param request_id the request id we are interested in + * @return the associated data + */ +void * +GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq, + uint32_t request_id); + + +/** + * Remove the association for a @a request_id + * + * @param mq the message queue with the association + * @param request_id the request id we want to remove + * @return the associated data + */ +void * +GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq, + uint32_t request_id); + + +/** + * Create a message queue for the specified handlers. + * + * @param send function the implements sending messages + * @param destroy function that implements destroying the queue + * @param cancel function that implements canceling a message + * @param impl_state for the queue, passed to @a send, @a destroy and @a cancel + * @param handlers array of message handlers + * @param error_handler handler for read and write errors + * @param cls closure for message handlers and error handler + * @return a new message queue + */ +struct GNUNET_MQ_Handle * +GNUNET_MQ_queue_for_callbacks (GNUNET_MQ_SendImpl send, + GNUNET_MQ_DestroyImpl destroy, + GNUNET_MQ_CancelImpl cancel, + void *impl_state, + const struct GNUNET_MQ_MessageHandler *handlers, + GNUNET_MQ_ErrorHandler error_handler, + void *cls); + + +/** + * Change the closure argument in all of the `handlers` of the + * @a mq. + * + * @param mq to modify + * @param handlers_cls new closure to use + */ +void +GNUNET_MQ_set_handlers_closure (struct GNUNET_MQ_Handle *mq, + void *handlers_cls); + + +/** + * Call a callback once the envelope has been sent, that is, + * sending it can not be canceled anymore. + * There can be only one notify sent callback per envelope. + * + * @param ev message to call the notify callback for + * @param cb the notify callback + * @param cb_cls closure for the callback + */ +void +GNUNET_MQ_notify_sent (struct GNUNET_MQ_Envelope *ev, + GNUNET_SCHEDULER_TaskCallback cb, + void *cb_cls); + + +/** + * Destroy the message queue. + * + * @param mq message queue to destroy + */ +void +GNUNET_MQ_destroy (struct GNUNET_MQ_Handle *mq); + + +/** + * Handle we return for callbacks registered to be + * notified when #GNUNET_MQ_destroy() is called on a queue. + */ +struct GNUNET_MQ_DestroyNotificationHandle; + + +/** + * Register function to be called whenever @a mq is being + * destroyed. + * + * @param mq message queue to watch + * @param cb function to call on @a mq destruction + * @param cb_cls closure for @a cb + * @return handle for #GNUNET_MQ_destroy_notify_cancel(). + */ +struct GNUNET_MQ_DestroyNotificationHandle * +GNUNET_MQ_destroy_notify (struct GNUNET_MQ_Handle *mq, + GNUNET_SCHEDULER_TaskCallback cb, + void *cb_cls); + +/** + * Cancel registration from #GNUNET_MQ_destroy_notify(). + * + * @param dnh handle for registration to cancel + */ +void +GNUNET_MQ_destroy_notify_cancel ( + struct GNUNET_MQ_DestroyNotificationHandle *dnh); + + +/** + * Call the message message handler that was registered + * for the type of the given message in the given message queue. + * + * This function is intended to be used for the implementation + * of message queues. + * + * @param mq message queue with the handlers + * @param mh message to dispatch + */ +void +GNUNET_MQ_inject_message (struct GNUNET_MQ_Handle *mq, + const struct GNUNET_MessageHeader *mh); + + +/** + * Call the error handler of a message queue with the given + * error code. If there is no error handler, log a warning. + * + * This function is intended to be used for the implementation + * of message queues. + * + * @param mq message queue + * @param error the error type + */ +void +GNUNET_MQ_inject_error (struct GNUNET_MQ_Handle *mq, + enum GNUNET_MQ_Error error); + + +/** + * Call the send implementation for the next queued message, if any. + * Calls the send notification for the current message unless + * #GNUNET_MQ_impl_send_in_flight was called for this envelope. + * + * Only useful for implementing message queues, results in undefined + * behavior if not used carefully. + * + * @param mq message queue to send the next message with + */ +void +GNUNET_MQ_impl_send_continue (struct GNUNET_MQ_Handle *mq); + + +/** + * Call the send notification for the current message, but do not + * try to send the next message until #gnunet_mq_impl_send_continue + * is called. + * + * Only useful for implementing message queues, results in undefined + * behavior if not used carefully. + * + * @param mq message queue to send the next message with + */ +void +GNUNET_MQ_impl_send_in_flight (struct GNUNET_MQ_Handle *mq); + + +/** + * Get the implementation state associated with the + * message queue. + * + * While the GNUNET_MQ_Impl* callbacks receive the + * implementation state, continuations that are scheduled + * by the implementation function often only have one closure + * argument, with this function it is possible to get at the + * implementation state when only passing the `struct GNUNET_MQ_Handle` + * as closure. + * + * @param mq message queue with the current message + * @return message to send, never NULL + */ +void * +GNUNET_MQ_impl_state (struct GNUNET_MQ_Handle *mq); + + +/** + * Get the message that should currently be sent. + * Fails if there is no current message. + * Only useful for implementing message queues, + * results in undefined behavior if not used carefully. + * + * @param mq message queue with the current message + * @return message to send, never NULL + */ +const struct GNUNET_MessageHeader * +GNUNET_MQ_impl_current (struct GNUNET_MQ_Handle *mq); + + +/** + * Enum defining all known preference categories. + * + * @deprecated will be replaced by `enum GNUNET_MQ_PriorityPreference` + */ +enum GNUNET_MQ_PreferenceKind +{ + /** + * No preference was expressed. + */ + GNUNET_MQ_PREFERENCE_NONE = 0, + + /** + * The preferred transmission for this envelope focuses on + * maximizing bandwidth. + */ + GNUNET_MQ_PREFERENCE_BANDWIDTH = 1, + + /** + * The preferred transmission for this envelope foces on + * minimizing latency. + */ + GNUNET_MQ_PREFERENCE_LATENCY = 2, + + /** + * The preferred transmission for this envelope foces on + * reliability. + */ + GNUNET_MQ_PREFERENCE_RELIABILITY = 3 + +/** + * Number of preference values allowed. + */ +#define GNUNET_MQ_PREFERENCE_COUNT 4 +}; + + +/** + * Convert an `enum GNUNET_MQ_PreferenceType` to a string + * + * @param type the preference type + * @return a string or NULL if invalid + * + * @deprecated will be replaced by `enum GNUNET_MQ_PriorityPreference` + */ +const char * +GNUNET_MQ_preference_to_string (enum GNUNET_MQ_PreferenceKind type); + + +#endif + +/** @} */ /* end of group mq */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_mst_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_mst_lib.h @@ -0,0 +1,177 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013, 2016 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 + * @{ + * + * @addtogroup networking + * @{ + * + * @author Christian Grothoff + * + * @file + * Library for tokenizing a message stream + + * @defgroup server Server library + * Library for tokenizing a message stream + * + * @see [Documentation](https://gnunet.org/mst) + * + * @{ + */ + +#if !defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_MST_LIB_H +#define GNUNET_MST_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Handle to a message stream tokenizer. + */ +struct GNUNET_MessageStreamTokenizer; + + +/** + * Functions with this signature are called whenever a + * complete message is received by the tokenizer. + * + * Do not call #GNUNET_mst_destroy from within + * the scope of this callback. + * + * @param cls closure + * @param message the actual message + * @return #GNUNET_OK on success, + * #GNUNET_NO to stop further processing due to disconnect (no error) + * #GNUNET_SYSERR to stop further processing due to error + */ +typedef int +(*GNUNET_MessageTokenizerCallback) (void *cls, + const struct GNUNET_MessageHeader *message); + + +/** + * Create a message stream tokenizer. + * + * @param cb function to call on completed messages + * @param cb_cls closure for @a cb + * @return handle to tokenizer + */ +struct GNUNET_MessageStreamTokenizer * +GNUNET_MST_create (GNUNET_MessageTokenizerCallback cb, + void *cb_cls); + + +/** + * Add incoming data to the receive buffer and call the + * callback for all complete messages. + * + * @param mst tokenizer to use + * @param buf input data to add + * @param size number of bytes in @a buf + * @param purge should any excess bytes in the buffer be discarded + * (i.e. for packet-based services like UDP) + * @param one_shot only call callback once, keep rest of message in buffer + * @return #GNUNET_OK if we are done processing (need more data) + * #GNUNET_NO if one_shot was set and we have another message ready + * #GNUNET_SYSERR if the data stream is corrupt + */ +enum GNUNET_GenericReturnValue +GNUNET_MST_from_buffer (struct GNUNET_MessageStreamTokenizer *mst, + const char *buf, + size_t size, + int purge, + int one_shot); + + +/** + * Add incoming data to the receive buffer and call the + * callback for all complete messages. + * + * @param mst tokenizer to use + * @param buf input data to add + * @param size number of bytes in @a buf + * @param purge should any excess bytes in the buffer be discarded + * (i.e. for packet-based services like UDP) + * @param one_shot only call callback once, keep rest of message in buffer + * @return #GNUNET_OK if we are done processing (need more data) + * #GNUNET_NO if one_shot was set and we have another message ready + * #GNUNET_SYSERR if the data stream is corrupt + */ +enum GNUNET_GenericReturnValue +GNUNET_MST_read (struct GNUNET_MessageStreamTokenizer *mst, + struct GNUNET_NETWORK_Handle *sock, + int purge, + int one_shot); + + +/** + * Obtain the next message from the @a mst, assuming that + * there are more unprocessed messages in the internal buffer + * of the @a mst. + * + * @param mst tokenizer to use + * @param one_shot only call callback once, keep rest of message in buffer + * @return #GNUNET_OK if we are done processing (need more data) + * #GNUNET_NO if one_shot was set and we have another message ready + * #GNUNET_SYSERR if the data stream is corrupt + */ +enum GNUNET_GenericReturnValue +GNUNET_MST_next (struct GNUNET_MessageStreamTokenizer *mst, + int one_shot); + + +/** + * Destroys a tokenizer. + * + * @param mst tokenizer to destroy + */ +void +GNUNET_MST_destroy (struct GNUNET_MessageStreamTokenizer *mst); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ /* end of group server */ + +/** @} */ /* end of group addition to networking */ + +/** @} */ /* end of group addition to libgnunetutil*/ + +/* end of gnunet_mst_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_nc_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_nc_lib.h @@ -0,0 +1,115 @@ +/* + This file is part of GNUnet. + Copyright (C) 2012-2016 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 + * + * @file + * General-purpose broadcast mechanism for message queues + * + * @defgroup mq NC library + * General-purpose broadcast mechanism for message queues + * + * @see [Documentation](https://gnunet.org/nc) + * + * @{ + */ +#ifndef GNUNET_NC_H +#define GNUNET_NC_H + + +/** + * The notification context is the key datastructure for a convenience + * API used for transmission of notifications to the subscriber until the + * subscriber disconnects (or the notification context is destroyed, in + * which case we disconnect these subscribers). Essentially, all + * (notification) messages are queued up until the subscriber is able to + * read them. + */ +struct GNUNET_NotificationContext; + + +/** + * Create a new notification context. + * + * @param queue_length maximum number of messages to keep in + * the notification queue; optional messages are dropped + * if the queue gets longer than this number of messages + * @return handle to the notification context + */ +struct GNUNET_NotificationContext * +GNUNET_notification_context_create (unsigned int queue_length); + + +/** + * Destroy the context, force disconnect for all subscribers. + * + * @param nc context to destroy. + */ +void +GNUNET_notification_context_destroy (struct GNUNET_NotificationContext *nc); + + +/** + * Add a subscriber to the notification context. + * + * @param nc context to modify + * @param mq message queue add + */ +void +GNUNET_notification_context_add (struct GNUNET_NotificationContext *nc, + struct GNUNET_MQ_Handle *mq); + + +/** + * Send a message to all subscribers of this context. + * + * @param nc context to modify + * @param msg message to send + * @param can_drop can this message be dropped due to queue length limitations + */ +void +GNUNET_notification_context_broadcast (struct GNUNET_NotificationContext *nc, + const struct GNUNET_MessageHeader *msg, + int can_drop); + +/** + * Return active number of subscribers in this context. + * + * @param nc context to query + * @return number of current subscribers + */ +unsigned int +GNUNET_notification_context_get_size (struct GNUNET_NotificationContext *nc); + +#endif + +/** @} */ /* end of group mq */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_network_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_network_lib.h @@ -0,0 +1,603 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013, 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 libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @addtogroup networking + * @{ + * + * @author Nils Durner + * @author Tobias Frisch + * + * @file + * Basic low-level networking interface + * + * @defgroup network Network library + * Basic low-level networking interface + * @{ + */ +#ifndef GNUNET_NETWORK_LIB_H +#define GNUNET_NETWORK_LIB_H + +#include "gnunet_common.h" +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +//#ifdef HAVE_SYS_SELECT_H +/* + * Include "sys/select.h" because it is required to use + * "fd_set" in "struct GNUNET_NETWORK_FDSet"! + */ + +#include <sys/select.h> +//#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif + +/** + * @brief handle to a socket + */ +struct GNUNET_NETWORK_Handle; + + +/** + * @brief collection of IO descriptors + */ +struct GNUNET_NETWORK_FDSet +{ + /** + * Maximum number of any socket descriptor in the set (plus one) + */ + int nsds; + + /** + * Bitset with the descriptors. + */ + fd_set sds; + +}; + +#include "gnunet_disk_lib.h" +#include "gnunet_time_lib.h" + +/** + * Test if the given protocol family is supported by this system. + * + * @param pf protocol family to test (PF_INET, PF_INET6, PF_UNIX) + * @return #GNUNET_OK if the PF is supported + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_test_pf (int pf); + + +/** + * Given a unixpath that is too long (larger than UNIX_PATH_MAX), + * shorten it to an acceptable length while keeping it unique + * and making sure it remains a valid filename (if possible). + * + * @param unixpath long path, will be freed (or same pointer returned + * with moved 0-termination). + * @return shortened unixpath, NULL on error + */ +char * +GNUNET_NETWORK_shorten_unixpath (char *unixpath); + + +/** + * If services crash, they can leave a unix domain socket file on the + * disk. This needs to be manually removed, because otherwise both + * bind() and connect() for the respective address will fail. In this + * function, we test if such a left-over file exists, and if so, + * remove it (unless there is a listening service at the address). + * + * @param un unix domain socket address to check + */ +void +GNUNET_NETWORK_unix_precheck (const struct sockaddr_un *un); + + +/** + * Accept a new connection on a socket. Configure it for non-blocking + * IO and mark it as non-inheritable to child processes (set the + * close-on-exec flag). + * + * @param desc bound socket + * @param address address of the connecting peer, may be NULL + * @param address_len length of address + * @return client socket + */ +struct GNUNET_NETWORK_Handle * +GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, + struct sockaddr *address, + socklen_t *address_len); + + +/** + * Box a native socket (and check that it is a socket). + * + * @param fd socket to box + * @return NULL on error (including not supported on target platform) + */ +struct GNUNET_NETWORK_Handle * +GNUNET_NETWORK_socket_box_native (int fd); + + +/** + * Set if a socket should use blocking or non-blocking IO. + * + * @param fd socket + * @param doBlock blocking mode + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, + int doBlock); + + +/** + * Bind a socket to a particular address. + * + * @param desc socket to bind + * @param address address to be bound + * @param address_len length of @a address + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc, + const struct sockaddr *address, + socklen_t address_len); + +/** + * Close a socket. + * + * @param desc socket to close + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc); + + +/** + * Only free memory of a socket, keep the file descriptor untouched. + * + * @param desc socket + */ +void +GNUNET_NETWORK_socket_free_memory_only_ (struct GNUNET_NETWORK_Handle *desc); + + +/** + * Connect a socket to some remote address. + * + * @param desc socket to connect + * @param address peer address + * @param address_len of @a address + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc, + const struct sockaddr *address, + socklen_t address_len); + + +/** + * Get socket options + * + * @param desc socket to inspect + * @param level protocol level of the option + * @param optname identifier of the option + * @param optval options + * @param optlen length of optval + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_getsockopt (const struct GNUNET_NETWORK_Handle *desc, + int level, + int optname, + void *optval, + socklen_t *optlen); + + +/** + * Listen on a socket + * + * @param desc socket to start listening on + * @param backlog length of the listen queue + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc, + int backlog); + + +/** + * How much data is available to be read on this descriptor? + * + * @param desc socket + * @returns #GNUNET_SYSERR if no data is available, or on error! + */ +ssize_t +GNUNET_NETWORK_socket_recvfrom_amount (const struct + GNUNET_NETWORK_Handle *desc); + + +/** + * Read data from a socket (always non-blocking). + * + * @param desc socket + * @param buffer buffer + * @param length length of buffer + * @param src_addr either the source to recv from, or all zeroes + * to be filled in by recvfrom + * @param addrlen length of the addr + */ +ssize_t +GNUNET_NETWORK_socket_recvfrom (const struct GNUNET_NETWORK_Handle *desc, + void *buffer, + size_t length, + struct sockaddr *src_addr, + socklen_t *addrlen); + + +/** + * Read data from a connected socket (always non-blocking). + * + * @param desc socket + * @param buffer buffer + * @param length length of buffer + * @return number of bytes read + */ +ssize_t +GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle *desc, + void *buffer, + size_t length); + + +/** + * Check if sockets meet certain conditions. + * + * @param rfds set of sockets to be checked for readability + * @param wfds set of sockets to be checked for writability + * @param efds set of sockets to be checked for exceptions + * @param timeout relative value when to return + * @return number of selected sockets, #GNUNET_SYSERR on error + */ +int +GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, + struct GNUNET_NETWORK_FDSet *wfds, + struct GNUNET_NETWORK_FDSet *efds, + struct GNUNET_TIME_Relative timeout); + + +/** + * Send data (always non-blocking). + * + * @param desc socket + * @param buffer data to send + * @param length size of the buffer + * @return number of bytes sent, #GNUNET_SYSERR on error + */ +ssize_t +GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle *desc, + const void *buffer, + size_t length); + + +/** + * Send data to a particular destination (always non-blocking). + * This function only works for UDP sockets. + * + * @param desc socket + * @param message data to send + * @param length size of the data in @a message + * @param dest_addr destination address + * @param dest_len length of @a dest_addr + * @return number of bytes sent, #GNUNET_SYSERR on error + */ +ssize_t +GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle *desc, + const void *message, + size_t length, + const struct sockaddr *dest_addr, + socklen_t dest_len); + + +/** + * Set socket option + * + * @param fd socket + * @param level protocol level of the option + * @param option_name option identifier + * @param option_value value to set + * @param option_len size of @a option_value + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +int +GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, + int level, + int option_name, + const void *option_value, + socklen_t option_len); + + +/** + * Shut down socket operations + * + * @param desc socket + * @param how type of shutdown + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, + int how); + + +/** + * Disable the "CORK" feature for communication with the given socket, + * forcing the OS to immediately flush the buffer on transmission + * instead of potentially buffering multiple messages. Essentially + * reduces the OS send buffers to zero. + * + * @param desc socket + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +GNUNET_NETWORK_socket_disable_corking (struct GNUNET_NETWORK_Handle *desc); + + +/** + * Create a new socket. Configure it for non-blocking IO and + * mark it as non-inheritable to child processes (set the + * close-on-exec flag). + * + * @param domain domain of the socket + * @param type socket type + * @param protocol network protocol + * @return new socket, NULL on error + */ +struct GNUNET_NETWORK_Handle * +GNUNET_NETWORK_socket_create (int domain, + int type, + int protocol); + + +/** + * Reset FD set (clears all file descriptors). + * + * @param fds fd set to clear + */ +void +GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds); + + +/** + * Add a socket to the FD set + * + * @param fds fd set + * @param desc socket to add + */ +void +GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds, + const struct GNUNET_NETWORK_Handle *desc); + + +/** + * Check whether a socket is part of the fd set + * + * @param fds fd set + * @param desc socket + * @return #GNUNET_YES if the socket is in the set + */ +int +GNUNET_NETWORK_fdset_isset (const struct GNUNET_NETWORK_FDSet *fds, + const struct GNUNET_NETWORK_Handle *desc); + + +/** + * Add one fd set to another (computes the union). + * + * @param dst the fd set to add to + * @param src the fd set to add from + */ +void +GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst, + const struct GNUNET_NETWORK_FDSet *src); + + +/** + * Copy one fd set to another + * + * @param to destination + * @param from source + */ +void +GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to, + const struct GNUNET_NETWORK_FDSet *from); + + +/** + * Return file descriptor for this network handle + * + * @param desc wrapper to process + * @return POSIX file descriptor + */ +int +GNUNET_NETWORK_get_fd (const struct GNUNET_NETWORK_Handle *desc); + + +/** + * Return the sockaddr for this network handle + * + * @param desc wrapper to process + * @return POSIX file descriptor + */ +struct sockaddr* +GNUNET_NETWORK_get_addr (const struct GNUNET_NETWORK_Handle *desc); + + +/** + * Return sockaddr length for this network handle + * + * @param desc wrapper to process + * @return socklen_t for sockaddr + */ +socklen_t +GNUNET_NETWORK_get_addrlen (const struct GNUNET_NETWORK_Handle *desc); + + +/** + * Copy a native fd set into the GNUnet representation. + * + * @param to destination + * @param from native source set + * @param nfds the biggest socket number in from + 1 + */ +void +GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to, + const fd_set *from, + int nfds); + + +/** + * Set a native fd in a set + * + * @param to destination + * @param nfd native FD to set + */ +void +GNUNET_NETWORK_fdset_set_native (struct GNUNET_NETWORK_FDSet *to, + int nfd); + + +/** + * Test native fd in a set + * + * @param to set to test, NULL for empty set + * @param nfd native FD to test, -1 for none + * @return #GNUNET_YES if to contains nfd + */ +int +GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to, + int nfd); + + +/** + * Add a file handle to the fd set + * + * @param fds fd set + * @param h the file handle to add + */ +void +GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds, + const struct GNUNET_DISK_FileHandle *h); + + +/** + * Add a file handle to the fd set + * On W32: ensure that the handle is first in the array. + * + * @param fds fd set + * @param h the file handle to add + */ +void +GNUNET_NETWORK_fdset_handle_set_first (struct GNUNET_NETWORK_FDSet *fds, + const struct GNUNET_DISK_FileHandle *h); + + +/** + * Check if a file handle is part of an fd set + * + * @param fds fd set + * @param h file handle + * @return #GNUNET_YES if the file handle is part of the set + */ +int +GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds, + const struct GNUNET_DISK_FileHandle *h); + + +/** + * Checks if two fd sets overlap + * + * @param fds1 first fd set + * @param fds2 second fd set + * @return #GNUNET_YES if they do overlap, #GNUNET_NO otherwise + */ +int +GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1, + const struct GNUNET_NETWORK_FDSet *fds2); + + +/** + * Creates an fd set + * + * @return a new fd set + */ +struct GNUNET_NETWORK_FDSet * +GNUNET_NETWORK_fdset_create (void); + + +/** + * Releases the associated memory of an fd set + * + * @param fds fd set + */ +void +GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds); + + +/** + * Test if the given @a port is available. + * + * @param ipproto transport protocol to test (e.g. IPPROTO_TCP) + * @param port port number to test + * @return #GNUNET_OK if the port is available, #GNUNET_NO if not + */ +int +GNUNET_NETWORK_test_port_free (int ipproto, + uint16_t port); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GNUNET_NETWORK_LIB_H */ + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_nt_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_nt_lib.h @@ -0,0 +1,134 @@ +/* + This file is part of GNUnet. + Copyright (C) 2010-2015, 2018 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 Backbone + * @{ + * + * @file network type characterization + * @author Christian Grothoff + * @author Matthias Wachs + * + * @defgroup nt Network type characterization + * + * @{ + */ +#ifndef GNUNET_NT_LIB_H +#define GNUNET_NT_LIB_H + +/** + * Types of networks (with separate quotas) we support. + */ +enum GNUNET_NetworkType +{ + /** + * Category of last resort. + */ + GNUNET_NT_UNSPECIFIED = 0, + + /** + * Loopback (same host). + */ + GNUNET_NT_LOOPBACK = 1, + + /** + * Local area network. + */ + GNUNET_NT_LAN = 2, + + /** + * Wide area network (i.e. Internet) + */ + GNUNET_NT_WAN = 3, + + /** + * Wireless LAN (i.e. 802.11abgn) + */ + GNUNET_NT_WLAN = 4, + + /** + * Bluetooth LAN + */ + GNUNET_NT_BT = 5 + +/** + * Number of network types supported by ATS + */ +#define GNUNET_NT_COUNT 6 +}; + + +/** + * Convert a `enum GNUNET_NetworkType` to a string + * + * @param net the network type + * @return a string or NULL if invalid + */ +const char * +GNUNET_NT_to_string (enum GNUNET_NetworkType net); + + +/** + * Handle for the LAN Characterization library. + */ +struct GNUNET_NT_InterfaceScanner; + + +/** + * Returns where the address is located: loopback, LAN or WAN. + * + * @param is handle from #GNUNET_ATS_interface_scanner_init() + * @param addr address + * @param addrlen address length + * @return type of the network the address belongs to + */ +enum GNUNET_NetworkType +GNUNET_NT_scanner_get_type (struct GNUNET_NT_InterfaceScanner *is, + const struct sockaddr *addr, + socklen_t addrlen); + + +/** + * Initialize the address characterization client handle. + * + * @return scanner handle, NULL on error + */ +struct GNUNET_NT_InterfaceScanner * +GNUNET_NT_scanner_init (void); + + +/** + * Terminate interface scanner. + * + * @param is scanner we are done with + */ +void +GNUNET_NT_scanner_done (struct GNUNET_NT_InterfaceScanner *is); + + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition to backbone */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_os_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_os_lib.h @@ -0,0 +1,713 @@ +/* + 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. + */ + char *gettext_domain; + + /** + * Gettext directory, e.g. the LOCALEDIR macro. + * If this field is NULL, the path is automatically inferred. + */ + 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. + */ + char *agpl_url; +}; + + +/** + * Return default project data used by 'libgnunetutil' for GNUnet. + */ +const struct GNUNET_OS_ProjectData * +GNUNET_OS_project_data_default (void); + + +/** + * @return current (actual) project data. + */ +const struct GNUNET_OS_ProjectData * +GNUNET_OS_project_data_get (void); + + +/** + * Setup OS subsystem with project data. + * + * @param pd project data used to determine paths. + */ +void +GNUNET_OS_init (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 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 (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 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 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 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_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/libgnunet/lib/arm64-v8a/include/gnunet_peer_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_peer_lib.h @@ -0,0 +1,140 @@ +/* + This file is part of GNUnet. + Copyright (C) 2006, 2009 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 + * + * @file + * Helper library for interning of peer identifiers + * + * @defgroup peer Peer library + * Helper library for interning of peer identifiers + * @{ + */ + +#ifndef GNUNET_PEER_LIB_H +#define GNUNET_PEER_LIB_H + + +#include "gnunet_util_lib.h" + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * A GNUNET_PEER_Id is simply a shorter version of a "struct + * GNUNET_PeerIdentifier" that can be used inside of a GNUnet peer to + * save memory when the same identifier needs to be used over and over + * again. + */ +typedef unsigned int GNUNET_PEER_Id; + + +/** + * Search for a peer identity. The reference counter is not changed. + * + * @param pid identity to find + * @return the interned identity or 0. + */ +GNUNET_PEER_Id +GNUNET_PEER_search (const struct GNUNET_PeerIdentity *pid); + + +/** + * Intern an peer identity. If the identity is already known, its + * reference counter will be increased by one. + * + * @param pid identity to intern + * @return the interned identity. + */ +GNUNET_PEER_Id +GNUNET_PEER_intern (const struct GNUNET_PeerIdentity *pid); + + +/** + * Change the reference counter of an interned PID. + * + * @param id identity to change the RC of + * @param delta how much to change the RC + */ +void +GNUNET_PEER_change_rc (GNUNET_PEER_Id id, int delta); + + +/** + * Decrement multiple RCs of peer identities by one. + * + * @param ids array of PIDs to decrement the RCs of + * @param count size of the @a ids array + */ +void +GNUNET_PEER_decrement_rcs (const GNUNET_PEER_Id *ids, + unsigned int count); + + +/** + * Convert an interned PID to a normal peer identity. + * + * @param id interned PID to convert + * @param pid where to write the normal peer identity + */ +void +GNUNET_PEER_resolve (GNUNET_PEER_Id id, + struct GNUNET_PeerIdentity *pid); + + +/** + * Convert an interned PID to a normal peer identity. + * + * @param id interned PID to convert + * @return pointer to peer identity, valid as long @a id is valid + */ +const struct GNUNET_PeerIdentity * +GNUNET_PEER_resolve2 (GNUNET_PEER_Id id); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_PEER_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_peer_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_peerstore_service.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_peerstore_service.h @@ -0,0 +1,428 @@ +/* + This file is part of GNUnet + Copyright (C) GNUnet e.V. 2004--2019 + + 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 Omar Tarabai + * + * @file + * API to the peerstore service + * + * @defgroup peerstore Peer Store service + * + * @see [Documentation](https://gnunet.org/gnunets-peerstore-subsystem) + * + * @{ + */ +#ifndef GNUNET_PEERSTORE_SERVICE_H +#define GNUNET_PEERSTORE_SERVICE_H + + +#include "gnunet_util_lib.h" + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * Key used for storing HELLO in the peerstore + */ +#define GNUNET_PEERSTORE_HELLO_KEY "peerstore-peer-hello-uri" + +/** + * Key used for storing addresses in URL format in the peerstore + */ +#define GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY "transport-communicator-url" + +/** + * Key used for storing HELLOs in the peerstore + */ +#define GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY "transport-peer-hello" + +/** + * Key used to store sender's monotonic time from backchannel + * messages. + */ +#define GNUNET_PEERSTORE_TRANSPORT_BACKCHANNEL_MONOTIME \ + "transport-backchannel-monotonic-time" + +/** + * Key used to store sender's monotonic time from DV learn + * messages. + */ +#define GNUNET_PEERSTORE_TRANSPORT_DVLEARN_MONOTIME \ + "transport-dv-learn-monotonic-time" + +/** + * Key used to store sender's monotonic time from handshake message. + */ +#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE \ + "transport-tcp-communicator-handshake" + +/** + * Key used to store sender's monotonic time from handshake ack message. + */ +#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK \ + "transport-tcp-communicator-handshake-ack" + +/** + * Key used to store sender's monotonic time from rekey message. + */ +#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY \ + "transport-tcp-communicator-rekey" + + +/** + * Options for storing values in PEERSTORE + */ +enum GNUNET_PEERSTORE_StoreOption +{ + /** + * Possibly store multiple values under given key. + */ + GNUNET_PEERSTORE_STOREOPTION_MULTIPLE = 0, + + /** + * Delete any previous values for the given key before + * storing the given value. + */ + GNUNET_PEERSTORE_STOREOPTION_REPLACE = 1, + +}; + +/** + * Handle to the peerstore service. + */ +struct GNUNET_PEERSTORE_Handle; + +/** + * Context for a store request + */ +struct GNUNET_PEERSTORE_StoreContext; + +/** + * Context for the info handler. + */ +struct GNUNET_PEERSTORE_NotifyContext; + +/** + * Single PEERSTORE record + */ +struct GNUNET_PEERSTORE_Record +{ + /** + * Responsible sub system string + */ + char *sub_system; + + /** + * Peer Identity + */ + struct GNUNET_PeerIdentity peer; + + /** + * Record key string + */ + char *key; + + /** + * Record value BLOB + */ + void *value; + + /** + * Size of @e value BLOB + */ + size_t value_size; + + /** + * Expiry time of entry + */ + struct GNUNET_TIME_Absolute expiry; + +}; + + +/** + * Continuation called with a status result. + * + * @param cls closure + * @param success #GNUNET_OK or #GNUNET_SYSERR + */ +typedef void (*GNUNET_PEERSTORE_Continuation) (void *cls, int success); + + +/** + * Context for a add hello uri request. + */ +struct GNUNET_PEERSTORE_StoreHelloContext; + + +/** + * Function called by PEERSTORE for each matching record. + * + * @param cls closure + * @param seq sequence in interation + * @param record peerstore record information + * @param emsg error message, or NULL if no errors + */ +typedef void (*GNUNET_PEERSTORE_Processor) ( + void *cls, + const struct GNUNET_PEERSTORE_Record *record, + const char *emsg); + +/** + * Function called by PEERSTORE when notifying a client about a changed hello. + * + * @param cls closure + * @param hello_uri Hello uri. + */ +typedef void (*GNUNET_PEERSTORE_hello_notify_cb) ( + void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *hello, + const char *err_msg); + +/** + * Add hello to peerstore. + * + * @param h handle for peerstore. + * @param msg The hello to add. + * @param cont The continuation function to execute after storing. + * @param cont_cls The continuation function closure. + * @return The context for storing. + */ +struct GNUNET_PEERSTORE_StoreHelloContext * +GNUNET_PEERSTORE_hello_add (struct GNUNET_PEERSTORE_Handle *h, + const struct GNUNET_MessageHeader *msg, + GNUNET_PEERSTORE_Continuation cont, + void *cont_cls); + + +/** + * Cancel the request to add a hello. + * + * @param huc The context for storing a hello. + */ +void +GNUNET_PEERSTORE_hello_add_cancel (struct + GNUNET_PEERSTORE_StoreHelloContext *huc); + + +/** + * Connect to the PEERSTORE service. + * + * @return NULL on error + */ +struct GNUNET_PEERSTORE_Handle * +GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Disconnect from the PEERSTORE service. Any pending ITERATE and WATCH and + * STORE requests will be canceled. + * + * @param h handle to disconnect + */ +void +GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h); + + +/** + * Store a new entry in the PEERSTORE. + * Note that stored entries can be lost in some cases + * such as power failure. + * + * @param h Handle to the PEERSTORE service + * @param sub_system name of the sub system + * @param peer Peer Identity + * @param key entry key + * @param value entry value BLOB + * @param size size of @e value + * @param expiry absolute time after which the entry is (possibly) deleted + * @param options options specific to the storage operation + * @param cont Continuation function after the store request is sent + * @param cont_cls Closure for @a cont + */ +struct GNUNET_PEERSTORE_StoreContext * +GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h, + const char *sub_system, + const struct GNUNET_PeerIdentity *peer, + const char *key, + const void *value, + size_t size, + struct GNUNET_TIME_Absolute expiry, + enum GNUNET_PEERSTORE_StoreOption options, + GNUNET_PEERSTORE_Continuation cont, + void *cont_cls); + + +/** + * Cancel a store request + * + * @param sc Store request context + */ +void +GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc); + + +/** + * Iterate over peerstore entries. + * The iteration can be filtered to contain only records + * matching @a peer and/or @a key. + * The @a sub_system to match must be provided. + * @a callback will be called with (each) matching record. + * #GNUNET_PEERSTORE_iteration_next() must be invoked + * to continue processing until the end of the iteration is + * reached. + * + * @param h handle to the PEERSTORE service + * @param sub_system name of sub system + * @param peer Peer identity (can be NULL) + * @param key entry key string (can be NULL) + * @param callback function called with each matching record. The record will be NULL to indicate end. + * @param callback_cls closure for @a callback + * @return Handle to iteration request + */ +struct GNUNET_PEERSTORE_IterateContext * +GNUNET_PEERSTORE_iteration_start (struct GNUNET_PEERSTORE_Handle *h, + const char *sub_system, + const struct GNUNET_PeerIdentity *peer, + const char *key, + GNUNET_PEERSTORE_Processor callback, + void *callback_cls); + + +/** + * Continue an iteration. + * Do NOT call after the iterate request is done. + * + * @param ic Iterate request context as returned by #GNUNET_PEERSTORE_iteration_start() + * @param limit how many records to return max until #GNUNET_PEERSTORE_iterate_next() needs to be called again. + */ +void +GNUNET_PEERSTORE_iteration_next (struct GNUNET_PEERSTORE_IterateContext *ic, + uint64_t limit); + + +/** + * Cancel an iteration. + * Do NOT call after the iterate request is done + * + * @param ic Iterate request context as returned by #GNUNET_PEERSTORE_iteration_start() + */ +void +GNUNET_PEERSTORE_iteration_stop (struct GNUNET_PEERSTORE_IterateContext *ic); + +/** + * Request watching a given key + * The monitoring can be filtered to contain only records + * matching @a peer and/or @a key. + * The @a sub_system to match must be provided. + * @a callback will be called with (each) matching new record. + * #GNUNET_PEERSTORE_monitor_next() must be invoked + * to continue processing until @a sync_cb is + * called, indicating that the caller should be up-to-date. + * The caller will be notified with any new values added to key + * through @a callback. + * If @a iterate_first is set to GNUNET_YES, the monitor will first + * iterate over all existing, matching records. In any case, + * after @a sync_cb is called the first time monitoring starts. + * + * @param h handle to the PEERSTORE service + * @param iterate_first first iterated of all results if GNUNET_YES + * @param sub_system name of sub system + * @param peer Peer identity + * @param key entry key string + * @param error_cb function to call on error (i.e. disconnect); note that + * unlike the other error callbacks in this API, a call to this + * function does NOT destroy the monitor handle, it merely signals + * that monitoring is down. You need to still explicitly call + * #GNUNET_PEERSTORE_monitor_stop(). + * @param error_cb_cls closure for @a error_cb + * @param sync_cb function called when we're in sync with the peerstore + * @param sync_cb_cls closure for @a sync_cb + * @param callback function called with each new value + * @param callback_cls closure for @a callback + * @return Handle to watch request + */ +struct GNUNET_PEERSTORE_Monitor * +GNUNET_PEERSTORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, + int iterate_first, + const char *sub_system, + const struct GNUNET_PeerIdentity *peer, + const char *key, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls, + GNUNET_SCHEDULER_TaskCallback sync_cb, + void *sync_cb_cls, + GNUNET_PEERSTORE_Processor callback, + void *callback_cls); + +/** + * Calls the monitor processor specified in #GNUNET_PEERSTORE_monitor_start + * for the next record(s). This function is used to allow clients that merely + * monitor the NAMESTORE to still throttle namestore operations, so we can be + * sure that the monitors can keep up. + * + * Note that #GNUNET_PEERSTORE_store() only waits for this + * call if the previous limit set by the client was already reached. + * Thus, by using a @a limit greater than 1, monitors basically enable + * a queue of notifications to be processed asynchronously with some + * delay. Note that even with a limit of 1 the + * #GNUNET_PEERSTORE_store() function will run asynchronously + * and the continuation may be invoked before the monitors completed + * (or even started) processing the notification. Thus, monitors will + * only closely track the current state of the peerstore, but not + * be involved in the transactions. + * + * @param zm the monitor + * @param limit number of records to return to the iterator in one shot + * (before #GNUNET_PEERSTORE_monitor_next is to be called again) + */ +void +GNUNET_PEERSTORE_monitor_next (struct GNUNET_PEERSTORE_Monitor *zm, + uint64_t limit); + +/** + * Stop monitoring. + * + * @param zm handle to the monitor activity to stop + */ +void +GNUNET_PEERSTORE_monitor_stop (struct GNUNET_PEERSTORE_Monitor *zm); + +#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/libgnunet/lib/arm64-v8a/include/gnunet_plugin_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_plugin_lib.h @@ -0,0 +1,179 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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 + * + * @file + * Plugin loading and unloading + * + * @defgroup plugin Plugin library + * Plugin loading and unloading + * @{ + */ + +#ifndef GNUNET_PLUGIN_LIB_H +#define GNUNET_PLUGIN_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Signature of any function exported by a plugin. + * + * @param arg argument to the function (context) + * @return some pointer, NULL if the plugin was + * shutdown or if there was an error, otherwise + * the plugin's API on success + */ +typedef void * +(*GNUNET_PLUGIN_Callback) (void *arg); + + +/** + * Test if a plugin exists. + * + * Note that the library must export a symbol called + * "library_name_init" for the test to succeed. + * + * @param library_name name of the plugin to test if it is installed + * @return #GNUNET_YES if the plugin exists, #GNUNET_NO if not + */ +enum GNUNET_GenericReturnValue +GNUNET_PLUGIN_test (const char *library_name); + + +/** + * Setup plugin (runs the "init" callback and returns whatever "init" + * returned). If "init" returns NULL, the plugin is unloaded. + * + * Note that the library must export symbols called + * "library_name_init" and "library_name_done". These will be called + * when the library is loaded and unloaded respectively. + * + * @param library_name name of the plugin to load + * @param arg argument to the plugin initialization function + * @return whatever the initialization function returned, NULL on error + */ +void * +GNUNET_PLUGIN_load (const char *library_name, + void *arg); + + +/** + * Signature of a function called by #GNUNET_PLUGIN_load_all(). + * + * @param cls closure + * @param library_name full name of the library (to be used with + * #GNUNET_PLUGIN_unload) + * @param lib_ret return value from the initialization function + * of the library (same as what #GNUNET_PLUGIN_load would + * have returned for the given library name) + */ +typedef void +(*GNUNET_PLUGIN_LoaderCallback) (void *cls, + const char *library_name, + void *lib_ret); + + +/** + * Load all compatible plugins with the given base name. + * + * Note that the library must export symbols called + * "basename_ANYTHING_init" and "basename_ANYTHING__done". These will + * be called when the library is loaded and unloaded respectively. + * + * @param basename basename of the plugins to load + * @param arg argument to the plugin initialization function + * @param cb function to call for each plugin found + * @param cb_cls closure for @a cb + */ +void +GNUNET_PLUGIN_load_all (const char *basename, + void *arg, + GNUNET_PLUGIN_LoaderCallback cb, + void *cb_cls); + + +/** + * Load all compatible plugins with the given base name while inside the given + * context (i.e. a specific project data structure.) + * + * Note that the library must export symbols called `basename_ANYTHING_init` + * and `basename_ANYTHING__done`. These will be called when the library is + * loaded and unloaded respectively. + * + * @param ctx the context used to find the plugins + * @param basename basename of the plugins to load + * @param arg argument to the plugin initialization function + * @param cb function to call for each plugin found + * @param cb_cls closure for @a cb + */ +void +GNUNET_PLUGIN_load_all_in_context (const struct GNUNET_OS_ProjectData *ctx, + const char *basename, + void *arg, + GNUNET_PLUGIN_LoaderCallback cb, + void *cb_cls); + + +/** + * Unload plugin (runs the "done" callback and returns whatever "done" + * returned). The plugin is then unloaded. + * + * @param library_name name of the plugin to unload + * @param arg argument to the plugin shutdown function + * @return whatever the shutdown function returned, typically NULL + * or a "char *" representing the error message + */ +void * +GNUNET_PLUGIN_unload (const char *library_name, + void *arg); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_PLUGIN_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_plugin_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_program_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_program_lib.h @@ -0,0 +1,179 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-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 + */ + +#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 + * + * @file + * Functions related to starting programs + * + * @defgroup program Program library + * Start command-line programs. + * @{ + */ + +#ifndef GNUNET_PROGRAM_LIB_H +#define GNUNET_PROGRAM_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_configuration_lib.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_scheduler_lib.h" + +/** + * Main function that will be run. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +typedef void +(*GNUNET_PROGRAM_Main) (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Run a standard GNUnet command startup sequence (initialize loggers + * and configuration, parse options). + * + * @param argc number of command line arguments in @a argv + * @param argv command line arguments + * @param binaryName our expected name + * @param binaryHelp help text for the program + * @param options command line options + * @param task main function to run + * @param task_cls closure for @a task + * @param run_without_scheduler #GNUNET_NO start the scheduler, + * #GNUNET_YES do not start the scheduler just run the main task + * @return #GNUNET_SYSERR on error, + * #GNUNET_NO if successful option processing called + * for the program to terminate, + * #GNUNET_OK on success (#a task was invoked) + */ +enum GNUNET_GenericReturnValue +GNUNET_PROGRAM_run2 (int argc, + char *const *argv, + const char *binaryName, + const char *binaryHelp, + const struct GNUNET_GETOPT_CommandLineOption *options, + GNUNET_PROGRAM_Main task, + void *task_cls, + int run_without_scheduler); + + +/** + * Run a standard GNUnet command startup sequence (initialize loggers + * and configuration, parse options). + * + * @param argc number of command line arguments + * @param argv command line arguments + * @param binaryName our expected name + * @param binaryHelp helptext for "-h" option (about the app) + * @param options command line options + * @param task main function to run + * @param task_cls closure for @a task + * @return #GNUNET_SYSERR on error, + * #GNUNET_NO if successful option processing called + * for the program to terminate, + * #GNUNET_OK on success (#a task was invoked) + */ +enum GNUNET_GenericReturnValue +GNUNET_PROGRAM_run (int argc, + char *const *argv, + const char *binaryName, + const char *binaryHelp, + const struct GNUNET_GETOPT_CommandLineOption *options, + GNUNET_PROGRAM_Main task, + void *task_cls); + +enum GNUNET_GenericReturnValue +GNUNET_DAEMON_register (const char *daemon_name, + const char *daemon_desc, + GNUNET_PROGRAM_Main task); + +#ifndef HAVE_GNUNET_MONOLITH +#define GNUNET_DAEMON_MAIN(daemon_name, daemon_help, init_cb) \ + int \ + main (int argc, \ + char *const *argv) \ + { \ + int ret; \ + struct GNUNET_GETOPT_CommandLineOption options[] = { \ + GNUNET_GETOPT_OPTION_END \ + }; \ + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, \ + &argv)) \ + return 2; \ + ret = GNUNET_PROGRAM_run (argc, \ + argv, \ + daemon_name, \ + daemon_help, \ + options, \ + init_cb, \ + NULL); \ + GNUNET_free_nz ((void*) argv); \ + return ret; \ + } +#else +#define GNUNET_DAEMON_MAIN(daemon_name, daemon_help, init_cb) \ + static int __attribute__ ((constructor)) \ + init (void) \ + { \ + return GNUNET_DAEMON_register (daemon_name, \ + daemon_help, \ + init_cb); \ + } +#endif + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_PROGRAM_LIB_H */ +#endif + +/** @} */ /* end of group program */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_program_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_protocols.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_protocols.h @@ -0,0 +1,3667 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001--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 + */ + +/** + * @addtogroup libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * @author Tobias Frisch + * + * @file + * Constants for network protocols + * + * @defgroup protocols Network protocol definitions + * Types of messages used in GNUnet. + * + * @see [Documentation](https://gnunet.org/ipc) + * + * @{ + */ + +/******************************************************************************* + * TODO: we need a way to register message types centrally (via some webpage). + * For now: unofficial extensions should start at 48k, internal extensions + * defined here should leave some room (4-10 additional messages to the previous + * extension). + ******************************************************************************/ + +#ifndef GNUNET_PROTOCOLS_H +#define GNUNET_PROTOCOLS_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/******************************************************************************* +* Deprecated +* *****************************************************************************/ + +/** + * Test if service is online. + * + * @deprecated! + */ +#define GNUNET_MESSAGE_TYPE_TEST 0 + +/******************************************************************************* +* AGPL source code download +* *****************************************************************************/ + +/** + * Message to request source code link. + */ +#define GNUNET_MESSAGE_TYPE_REQUEST_AGPL 1 + +/** + * Source code link. + */ +#define GNUNET_MESSAGE_TYPE_RESPONSE_AGPL 2 + +/******************************************************************************* + * RESOLVER message types + ******************************************************************************/ + +/** + * Request DNS resolution. + */ +#define GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST 4 + +/** + * Response to a DNS resolution request. + */ +#define GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE 5 + +/******************************************************************************* + * UTIL message types + ******************************************************************************/ + +/** + * Dummy messages for testing / benchmarking. + */ +#define GNUNET_MESSAGE_TYPE_DUMMY 6 + +/** + * Another dummy messages for testing / benchmarking. + */ +#define GNUNET_MESSAGE_TYPE_DUMMY2 7 + + +/******************************************************************************* + * ARM message types + ******************************************************************************/ + +/** + * Request to ARM to start a service. + */ +#define GNUNET_MESSAGE_TYPE_ARM_START 8 + +/** + * Request to ARM to stop a service. + */ +#define GNUNET_MESSAGE_TYPE_ARM_STOP 9 + +/** + * Response from ARM. + */ +#define GNUNET_MESSAGE_TYPE_ARM_RESULT 10 + +/** + * Status update from ARM. + */ +#define GNUNET_MESSAGE_TYPE_ARM_STATUS 11 + +/** + * Request to ARM to list all currently running services + */ +#define GNUNET_MESSAGE_TYPE_ARM_LIST 12 + +/** + * Response from ARM for listing currently running services + */ +#define GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT 13 + +/** + * Request to ARM to notify client of service status changes + */ +#define GNUNET_MESSAGE_TYPE_ARM_MONITOR 14 + +/** + * Test if ARM service is online. + */ +#define GNUNET_MESSAGE_TYPE_ARM_TEST 15 + +/******************************************************************************* + * HELLO message types + ******************************************************************************/ + +/** + * Latest HELLO messages used for communicating peer addresses. + * Managed by libgnunethello. + */ +#define GNUNET_MESSAGE_TYPE_HELLO_URI 16 + +/** + * HELLO message with friend only flag used for communicating peer addresses. + * Managed by libgnunethello. + */ + +#define GNUNET_MESSAGE_TYPE_HELLO 17 + +/******************************************************************************* + * FRAGMENTATION message types + ******************************************************************************/ + +/** + * FRAGMENT of a larger message. + * Managed by libgnunetfragment. + */ +#define GNUNET_MESSAGE_TYPE_FRAGMENT 18 + +/** + * Acknowledgement of a FRAGMENT of a larger message. + * Managed by libgnunetfragment. + */ +#define GNUNET_MESSAGE_TYPE_FRAGMENT_ACK 19 + +/******************************************************************************* + * Transport-WLAN message types + ******************************************************************************/ + +/** + * Type of data messages from the plugin to the gnunet-wlan-helper + */ +#define GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER 39 + +/** + * Type of data messages from the gnunet-wlan-helper to the plugin + */ +#define GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER 40 + +/** + * Control message between the gnunet-wlan-helper and the daemon (with the MAC). + */ +#define GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL 41 + +/** + * Type of messages for advertisement over wlan + */ +#define GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT 42 + +/** + * Type of messages for data over the wlan + */ +#define GNUNET_MESSAGE_TYPE_WLAN_DATA 43 + + +/******************************************************************************* + * Transport-DV message types + ******************************************************************************/ + +/** + * DV service to DV Plugin message, when a message is + * unwrapped by the DV service and handed to the plugin + * for processing + */ +#define GNUNET_MESSAGE_TYPE_DV_RECV 44 + +/** + * DV Plugin to DV service message, indicating a message + * should be sent out. + */ +#define GNUNET_MESSAGE_TYPE_DV_SEND 45 + +/** + * DV service to DV api message, containing a confirmation + * or failure of a DV_SEND message. + */ +#define GNUNET_MESSAGE_TYPE_DV_SEND_ACK 46 + +/** + * P2P DV message encapsulating some real message + */ +#define GNUNET_MESSAGE_TYPE_DV_ROUTE 47 + +/** + * DV Plugin to DV service message, indicating + * startup. + */ +#define GNUNET_MESSAGE_TYPE_DV_START 48 + +/** + * P2P DV message telling plugin that a peer connected + */ +#define GNUNET_MESSAGE_TYPE_DV_CONNECT 49 + +/** + * P2P DV message telling plugin that a peer disconnected + */ +#define GNUNET_MESSAGE_TYPE_DV_DISCONNECT 50 + +/** + * P2P DV message telling plugin that a message transmission failed (negative + * ACK) + */ +#define GNUNET_MESSAGE_TYPE_DV_SEND_NACK 51 + +/** + * P2P DV message telling plugin that our distance to a peer changed + */ +#define GNUNET_MESSAGE_TYPE_DV_DISTANCE_CHANGED 52 + +/** + * DV message box for boxing multiple messages. + */ +#define GNUNET_MESSAGE_TYPE_DV_BOX 53 + + +/** + * Experimental message type. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_XU_MESSAGE 55 + + +/******************************************************************************* + * Transport-UDP message types + ******************************************************************************/ + +/** + * Normal UDP message type. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE 56 + +/** + * UDP ACK. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK 57 + +/******************************************************************************* + * Transport-TCP message types + ******************************************************************************/ + +/** + * TCP NAT probe message, send from NAT'd peer to + * other peer to establish bi-directional communication + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE 60 + +/** + * Welcome message between TCP transports. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME 61 + +/** + * Message to force transport to update bandwidth assignment (LEGACY) + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ATS 62 + +/******************************************************************************* + * NAT message types + ******************************************************************************/ + +/** + * Message to ask NAT server to perform traversal test + */ +#define GNUNET_MESSAGE_TYPE_NAT_TEST 63 + +/******************************************************************************* + * CORE message types + ******************************************************************************/ + +/** + * Initial setup message from core client to core. + */ +#define GNUNET_MESSAGE_TYPE_CORE_INIT 64 + +/** + * Response from core to core client to INIT message. + */ +#define GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY 65 + +/** + * Notify clients about new peer-to-peer connections (triggered + * after key exchange). + */ +#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT 67 + +/** + * Notify clients about peer disconnecting. + */ +#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT 68 + +/** + * Notify clients about peer status change. + */ +#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE 69 + +/** + * Notify clients about incoming P2P messages. + */ +#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 70 + +/** + * Notify clients about outgoing P2P transmissions. + */ +#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 71 + +/** + * Request from client to transmit message. + */ +#define GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST 74 + +/** + * Confirmation from core that message can now be sent + */ +#define GNUNET_MESSAGE_TYPE_CORE_SEND_READY 75 + +/** + * Client with message to transmit (after SEND_READY confirmation + * was received). + */ +#define GNUNET_MESSAGE_TYPE_CORE_SEND 76 + +/** + * Request for connection monitoring from CORE service. + */ +#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS 78 + +/** + * Reply for monitor by CORE service. + */ +#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY 79 + +/** + * Encapsulation for an encrypted message between peers. + */ +#define GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE 82 + +/** + * Check that other peer is alive (challenge). + */ +#define GNUNET_MESSAGE_TYPE_CORE_PING 83 + +/** + * Confirmation that other peer is alive. + */ +#define GNUNET_MESSAGE_TYPE_CORE_PONG 84 + +/** + * Request by the other peer to terminate the connection. + */ +#define GNUNET_MESSAGE_TYPE_CORE_HANGUP 85 + +/** + * gzip-compressed type map of the sender + */ +#define GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP 86 + +/** + * uncompressed type map of the sender + */ +#define GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP 87 + +/** + * Session key exchange between peers. + */ +#define GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY 88 + +/** + * Other peer confirms having received the type map + */ +#define GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP 89 + + +/******************************************************************************* + * DATASTORE message types + ******************************************************************************/ + +/** + * Message sent by datastore client on join. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_RESERVE 92 + +/** + * Message sent by datastore client on join. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_RELEASE_RESERVE 93 + +/** + * Message sent by datastore to client informing about status + * processing a request + * (in response to RESERVE, RELEASE_RESERVE, PUT, UPDATE and REMOVE requests). + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_STATUS 94 + +/** + * Message sent by datastore client to store data. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_PUT 95 + +/** + * Message sent by datastore client to get data. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_GET 97 + +/** + * Message sent by datastore client to get random data. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_REPLICATION 98 + +/** + * Message sent by datastore client to get random data. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_ZERO_ANONYMITY 99 + +/** + * Message sent by datastore to client providing requested data + * (in response to GET or GET_RANDOM request). + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA 100 + +/** + * Message sent by datastore to client signaling end of matching data. + * This message will also be sent for "GET_RANDOM", even though + * "GET_RANDOM" returns at most one data item. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END 101 + +/** + * Message sent by datastore client to remove data. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE 102 + +/** + * Message sent by datastore client to drop the database. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_DROP 103 + +/** + * Message sent by datastore client to get data by key. + */ +#define GNUNET_MESSAGE_TYPE_DATASTORE_GET_KEY 104 + + +/******************************************************************************* + * FS message types + ******************************************************************************/ + +/** + * Message sent by fs client to request LOC signature. + */ +#define GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGN 126 + +/** + * Reply sent by fs service with LOC signature. + */ +#define GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGNATURE 127 + +/** + * Message sent by fs client to start indexing. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_START 128 + +/** + * Affirmative response to a request for start indexing. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK 129 + +/** + * Response to a request for start indexing that + * refuses. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_START_FAILED 130 + +/** + * Request from client for list of indexed files. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET 131 + +/** + * Reply to client with an indexed file name. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY 132 + +/** + * Reply to client indicating end of list. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END 133 + +/** + * Request from client to unindex a file. + */ +#define GNUNET_MESSAGE_TYPE_FS_UNINDEX 134 + +/** + * Reply to client indicating unindex receipt. + */ +#define GNUNET_MESSAGE_TYPE_FS_UNINDEX_OK 135 + +/** + * Client asks FS service to start a (keyword) search. + */ +#define GNUNET_MESSAGE_TYPE_FS_START_SEARCH 136 + +/** + * P2P request for content (one FS to another). + */ +#define GNUNET_MESSAGE_TYPE_FS_GET 137 + +/** + * P2P response with content or active migration of content. Also + * used between the service and clients (in response to + * #GNUNET_MESSAGE_TYPE_FS_START_SEARCH). + */ +#define GNUNET_MESSAGE_TYPE_FS_PUT 138 + +/** + * Peer asks us to stop migrating content towards it for a while. + */ +#define GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP 139 + +/** + * P2P request for content (one FS to another via a cadet). + */ +#define GNUNET_MESSAGE_TYPE_FS_CADET_QUERY 140 + +/** + * P2P answer for content (one FS to another via a cadet). + */ +#define GNUNET_MESSAGE_TYPE_FS_CADET_REPLY 141 + + +/******************************************************************************* + * DHT message types + ******************************************************************************/ +/** + * Client wants to store item in DHT. + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT 142 + +/** + * Client wants to lookup item in DHT. + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET 143 + +/** + * Client wants to stop search in DHT. + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP 144 + +/** + * Service returns result to client. + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT 145 + +/** + * Peer is storing data in DHT. + */ +#define GNUNET_MESSAGE_TYPE_DHT_P2P_PUT 146 + +/** + * Peer tries to find data in DHT. + */ +#define GNUNET_MESSAGE_TYPE_DHT_P2P_GET 147 + +/** + * Data is returned to peer from DHT. + */ +#define GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT 148 + +/** + * Receive information about transiting GETs + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET 149 + +/** + * Receive information about transiting GET responses + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP 150 + +/** + * Receive information about transiting PUTs + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT 151 + +/** + * Receive information about transiting PUT responses (TODO) + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT_RESP 152 + +/** + * Request information about transiting messages + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_START 153 + +/** + * Stop information about transiting messages + */ +#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP 154 + +/** + * Certain results are already known to the client, filter those. + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN 156 + +/** + * HELLO advertising a neighbours addresses. + */ +#define GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO 157 + +/** + * Encapsulation of DHT messages in CORE service. + */ +#define GNUNET_MESSAGE_TYPE_DHT_CORE 158 + +/** + * HELLO URL send between client and service (in + * either direction). + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL 159 + +/** + * Client requests DHT service's HELLO URL. + */ +#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_GET 161 + + +/******************************************************************************* + * HOSTLIST message types + ******************************************************************************/ + +/** + * Hostlist advertisement message + */ +#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT 160 + + +/******************************************************************************* + * STATISTICS message types + ******************************************************************************/ + +/** + * Set a statistical value. + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_SET 168 + +/** + * Get a statistical value(s). + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_GET 169 + +/** + * Response to a STATISTICS_GET message (with value). + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_VALUE 170 + +/** + * Response to a STATISTICS_GET message (end of value stream). + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_END 171 + +/** + * Watch changes to a statistical value. Message format is the same + * as for GET, except that the subsystem and entry name must be given. + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH 172 + +/** + * Changes to a watched value. + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE 173 + +/** + * Client is done sending service requests and will now disconnect. + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT 174 + +/** + * Service confirms disconnect and that it is done processing + * all requests from the client. + */ +#define GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM 175 + +/******************************************************************************* + * VPN message types + ******************************************************************************/ + +/** + * Type of messages between the gnunet-vpn-helper and the daemon + */ +#define GNUNET_MESSAGE_TYPE_VPN_HELPER 185 + +/** + * Type of messages containing an ICMP packet for a service. + */ +#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE 190 + +/** + * Type of messages containing an ICMP packet for the Internet. + */ +#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET 191 + +/** + * Type of messages containing an ICMP packet for the VPN + */ +#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN 192 + +/** + * Type of messages containing an DNS request for a DNS exit service. + */ +#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET 193 + +/** + * Type of messages containing an DNS reply from a DNS exit service. + */ +#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET 194 + +/** + * Type of messages containing an TCP packet for a service. + */ +#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START 195 + +/** + * Type of messages containing an TCP packet for the Internet. + */ +#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START 196 + +/** + * Type of messages containing an TCP packet of an established connection. + */ +#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT 197 + +/** + * Type of messages containing an TCP packet of an established connection. + */ +#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN 198 + +/** + * Type of messages containing an UDP packet for a service. + */ +#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE 199 + +/** + * Type of messages containing an UDP packet for the Internet. + */ +#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET 200 + +/** + * Type of messages containing an UDP packet from a remote host + */ +#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY 201 + + +/** + * Client asks VPN service to setup an IP to redirect traffic + * via an exit node to some global IP address. + */ +#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP 202 + +/** + * Client asks VPN service to setup an IP to redirect traffic + * to some peer offering a service. + */ +#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE 203 + +/** + * VPN service responds to client with an IP to use for the + * requested redirection. + */ +#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP 204 + + +/******************************************************************************* + * VPN-DNS message types + ******************************************************************************/ + + +/** + * Initial message from client to DNS service for registration. + */ +#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_INIT 211 + +/** + * Type of messages between the gnunet-helper-dns and the service + */ +#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_REQUEST 212 + +/** + * Type of messages between the gnunet-helper-dns and the service + */ +#define GNUNET_MESSAGE_TYPE_DNS_CLIENT_RESPONSE 213 + +/** + * Type of messages between the gnunet-helper-dns and the service + */ +#define GNUNET_MESSAGE_TYPE_DNS_HELPER 214 + + +/******************************************************************************* + * CHAT message types START + ******************************************************************************/ + +/** + * Message sent from client to join a chat room. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_JOIN_REQUEST 300 + +/** + * Message sent to client to indicate joining of another room member. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION 301 + +/** + * Message sent to client to indicate leaving of another room member. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_LEAVE_NOTIFICATION 302 + +/** + * Notification sent by service to client indicating that we've received a chat + * message. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION 303 + +/** + * Request sent by client to transmit a chat message to another room members. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_TRANSMIT_REQUEST 304 + +/** + * Receipt sent from a message receiver to the service to confirm delivery of + * a chat message. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT 305 + +/** + * Notification sent from the service to the original sender + * to acknowledge delivery of a chat message. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION 306 + +/** + * P2P message sent to indicate joining of another room member. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_P2P_JOIN_NOTIFICATION 307 + +/** + * P2P message sent to indicate leaving of another room member. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_P2P_LEAVE_NOTIFICATION 308 + +/** + * P2P message sent to a newly connected peer to request its known clients in + * order to synchronize room members. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_P2P_SYNC_REQUEST 309 + +/** + * Notification sent from one peer to another to indicate that we have received + * a chat message. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_P2P_MESSAGE_NOTIFICATION 310 + +/** + * P2P receipt confirming delivery of a chat message. + */ +#define GNUNET_MESSAGE_TYPE_CHAT_P2P_CONFIRMATION_RECEIPT 311 + + +/******************************************************************************* + * NSE (network size estimation) message types + ******************************************************************************/ + +/** + * client->service message indicating start + */ +#define GNUNET_MESSAGE_TYPE_NSE_START 321 + +/** + * P2P message sent from nearest peer + */ +#define GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD 322 + +/** + * service->client message indicating + */ +#define GNUNET_MESSAGE_TYPE_NSE_ESTIMATE 323 + + +/******************************************************************************* + * PEERINFO message types + ******************************************************************************/ + +/** + * Request update and listing of a peer. + */ +#define GNUNET_MESSAGE_TYPE_PEERINFO_GET 330 + +/** + * Request update and listing of all peers. + */ +#define GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL 331 + +/** + * Information about one of the peers. + */ +#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO 332 + +/** + * End of information about other peers. + */ +#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END 333 + +/** + * Start notifying this client about all changes to + * the known peers until it disconnects. + */ +#define GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY 334 + +/******************************************************************************* + * ATS message types + ******************************************************************************/ + +/** + * Type of the 'struct ClientStartMessage' sent by clients to ATS to + * identify the type of the client. + */ +#define GNUNET_MESSAGE_TYPE_ATS_START 340 + +/** + * Type of the 'struct RequestAddressMessage' sent by clients to ATS + * to request an address to help connect. + */ +#define GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS 341 + +/** + * Type of the 'struct RequestAddressMessage' sent by clients to ATS + * to request an address to help connect. + */ +#define GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL 342 + +/** + * Type of the 'struct AddressUpdateMessage' sent by clients to ATS + * to inform ATS about performance changes. + */ +#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE 343 + +/** + * Type of the 'struct AddressDestroyedMessage' sent by clients to ATS + * to inform ATS about an address being unavailable. + */ +#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED 344 + +/** + * Type of the 'struct AddressSuggestionMessage' sent by ATS to clients + * to suggest switching to a different address. + */ +#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION 345 + +/** + * Type of the 'struct PeerInformationMessage' sent by ATS to clients + * to inform about QoS for a particular connection. + */ +#define GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION 346 + +/** + * Type of the 'struct ReservationRequestMessage' sent by clients to ATS + * to ask for inbound bandwidth reservations. + */ +#define GNUNET_MESSAGE_TYPE_ATS_RESERVATION_REQUEST 347 + +/** + * Type of the 'struct ReservationResultMessage' sent by ATS to clients + * in response to a reservation request. + */ +#define GNUNET_MESSAGE_TYPE_ATS_RESERVATION_RESULT 348 + +/** + * Type of the 'struct ChangePreferenceMessage' sent by clients to ATS + * to ask for allocation preference changes. + */ +#define GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE 349 + +/** + * Type of the 'struct SessionReleaseMessage' sent by ATS to client + * to confirm that a session ID was destroyed. + */ +#define GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE 350 + +/** + * Type of the 'struct AddressUpdateMessage' sent by client to ATS + * to add a new address + */ +#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD 353 + +/** + * Type of the 'struct AddressListRequestMessage' sent by client to ATS + * to request information about addresses + */ +#define GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST 354 + +/** + * Type of the 'struct AddressListResponseMessage' sent by ATS to client + * with information about addresses + */ +#define GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE 355 + +/** + * Type of the 'struct ChangePreferenceMessage' sent by clients to ATS + * to ask for allocation preference changes. + */ +#define GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_FEEDBACK 356 + + +/******************************************************************************* + * TRANSPORT message types + ******************************************************************************/ + +/** + * Message from the core saying that the transport + * server should start giving it messages. This + * should automatically trigger the transmission of + * a HELLO message. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_START 360 + +/** + * Message from TRANSPORT notifying about a + * client that connected to us. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT 361 + +/** + * Message from TRANSPORT notifying about a + * client that disconnected from us. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT 362 + +/** + * Request to TRANSPORT to transmit a message. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND 363 + +/** + * Confirmation from TRANSPORT that message for transmission has been + * queued (and that the next message to this peer can now be passed to + * the service). Note that this confirmation does NOT imply that the + * message was fully transmitted. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK 364 + +/** + * Message from TRANSPORT notifying about a + * message that was received. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_RECV 365 + +/** + * Message telling transport to limit its receive rate. + * (FIXME: was the above comment ever accurate?) + * + * Note: dead in TNG, replaced by RECV_OK! + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA 366 + +/** + * Message telling transport to limit its receive rate. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_RECV_OK 366 + +/** + * Request to look addresses of peers in server. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING 367 + +/** + * Response to the address lookup request. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY 368 + +/** + * Register a client that wants to do blacklisting. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT 369 + +/** + * Query to a blacklisting client (is this peer blacklisted)? + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY 370 + +/** + * Reply from blacklisting client (answer to blacklist query). + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY 371 + +/** + * Transport PING message + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_PING 372 + +/** + * Transport PONG message + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_PONG 373 + +/** + * Transport SYN message exchanged between transport services to + * indicate that a session should be marked as 'connected'. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN 375 + +/** + * Transport SYN_ACK message exchanged between transport services to + * indicate that a SYN message was accepted + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK 376 + +/** + * Transport ACK message exchanged between transport services to + * indicate that a SYN_ACK message was accepted + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK 377 + +/** + * Transport DISCONNECT message exchanged between transport services to + * indicate that a connection should be dropped. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT 378 + +/** + * Message exchanged between transport services to + * indicate that the sender should limit its transmission + * rate to the indicated quota. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA 379 + +/** + * Request to monitor addresses used by a peer or all peers. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST 380 + +/** + * Message send by a peer to notify the other to keep the session alive + * and measure latency in a regular interval + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE 381 + +/** + * Response to a #GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE message to + * measure latency in a regular interval + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE 382 + +/** + * Response to #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST + * request to iterate over all known addresses. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE 383 + +/** + * Message send by a peer to notify the other to keep the session alive. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON 384 + +/** + * Message containing traffic metrics for transport service + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC 385 + +/** + * Request to start monitoring the connection state of plugins. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_START 388 + +/** + * Monitoring event about the connection state of plugins, + * generated in response to a subscription initiated via + * #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_START + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_EVENT 389 + +/** + * Monitoring event notifying client that the initial iteration + * is now completed and we are in sync with the state of the subsystem. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_SYNC 390 + +/** + * Response to #GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END + * terminating list of replies. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END 391 + + +/******************************************************************************* + * FS-PUBLISH-HELPER IPC Messages + ******************************************************************************/ + +/** + * Progress information from the helper: found a file + */ +#define GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_FILE 420 + +/** + * Progress information from the helper: found a directory + */ +#define GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY 421 + +/** + * Error signal from the helper. + */ +#define GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR 422 + +/** + * Signal that helper skipped a file. + */ +#define GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE 423 + +/** + * Signal that helper is done scanning the directory tree. + */ +#define GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE 424 + +/** + * Extracted meta data from the helper. + */ +#define GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA 425 + +/** + * Signal that helper is done. + */ +#define GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED 426 + + +/******************************************************************************* + * NAMECACHE message types + ******************************************************************************/ + +/** + * Client to service: lookup block + */ +#define GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK 431 + +/** + * Service to client: result of block lookup + */ +#define GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK_RESPONSE 432 + +/** + * Client to service: cache a block + */ +#define GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE 433 + +/** + * Service to client: result of block cache request + */ +#define GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE_RESPONSE 434 + +/******************************************************************************* + * NAMESTORE message types + ******************************************************************************/ + +/** + * Client to service: store records (as authority) + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE 435 + +/** + * Service to client: result of store operation. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_GENERIC_RESPONSE 436 + +/** + * Client to service: lookup label + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP 437 + +/** + * Service to client: lookup label + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE 438 + +/** + * Client to service: "reverse" lookup for zone name based on zone key + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME 439 + +/** + * Service to client: result of zone-to-name lookup. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE 440 + +/** + * Client to service: start monitoring (yields sequence of + * "ZONE_ITERATION_RESPONSES" --- forever). + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START 441 + +/** + * Service to client: you're now in sync. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC 442 + +/** + * Service to client: here is a (plaintext) record you requested. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT 443 + +/** + * Client to service: I am now ready for the next (set of) monitor + * events. Monitoring equivlaent of + * #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT 444 + +/** + * Client to service: please start iteration; receives + * "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE" messages in return. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START 445 + +/** + * Client to service: next record(s) in iteration please. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT 447 + +/** + * Client to service: stop iterating. + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP 448 + +/** + * Service to client: end of list of results + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END 449 + + +/******************************************************************************* + * LOCKMANAGER message types + ******************************************************************************/ + +/** + * Message to acquire Lock + */ +#define GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE 450 + +/** + * Message to release lock + */ +#define GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE 451 + +/** + * SUCCESS reply from lockmanager + */ +#define GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS 452 + +/******************************************************************************* + * TESTBED message types + ******************************************************************************/ + +/** + * Initial message from a client to a testing control service + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_INIT 460 + +/** + * Message to add host + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST 461 + +/** + * Message to signal that a add host succeeded + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST_SUCCESS 462 + +/** + * Message to link delegated controller to slave controller + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS 463 + +/** + * Message to create a peer at a host + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER 464 + +/** + * Message to reconfigure a peer + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_RECONFIGURE_PEER 465 + +/** + * Message to start a peer at a host + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_START_PEER 466 + +/** + * Message to stop a peer at a host + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER 467 + +/** + * Message to destroy a peer + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_DESTROY_PEER 468 + +/** + * Configure underlay link message + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_CONFIGURE_UNDERLAY_LINK 469 + +/** + * Message to connect peers in a overlay + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT 470 + +/** + * Message for peer events + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT 471 + +/** + * Message for peer connect events + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_PEER_CONNECT_EVENT 472 + +/** + * Message for operation events + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_OPERATION_FAIL_EVENT 473 + +/** + * Message to signal successful peer creation + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS 474 + +/** + * Message to signal a generic operation has been successful + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS 475 + +/** + * Message to get a peer's information + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION 476 + +/** + * Message containing the peer's information + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_PEER_INFORMATION 477 + +/** + * Message to request a controller to make one of its peer to connect to another + * peer using the contained HELLO + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT 478 + +/** + * Message to request configuration of a slave controller + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION 479 + +/** + * Message which contains the configuration of slave controller + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION 480 + +/** + * Message to signal the result of #GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS + * request + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS_RESULT 481 + +/** + * A controller receiving this message floods it to its directly-connected + * sub-controllers and then stops and destroys all peers + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS 482 + +/** + * Message to start/stop a service of a peer + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE 483 + +/** + * Message to initialise a barrier. Messages of these type are flooded to all + * sub-controllers + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT 484 + +/** + * Message to cancel a barrier. This message is flooded to all sub-controllers + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL 485 + +/** + * Message for signalling status of a barrier + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS 486 + +/** + * Message sent by a peer when it has reached a barrier and is waiting for it to + * be crossed + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT 487 + +/** + * Not really a message, but for careful checks on the testbed messages; Should + * always be the maximum and never be used to send messages with this type + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_MAX 488 + +/** + * The initialization message towards gnunet-testbed-helper + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT 495 + +/** + * The reply message from gnunet-testbed-helper + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY 496 + + +/****************************************************************************** + * GNS. + *****************************************************************************/ + +/** + * Client would like to resolve a name. + */ +#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP 500 + +/** + * Service response to name resolution request from client. + */ +#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT 501 + +/** + * Reverse lookup + */ +#define GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP 503 + +/** + * Response to reverse lookup + */ +#define GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT 504 + + +/******************************************************************************* + * CONSENSUS message types + ******************************************************************************/ + +/** + * Join a consensus session. Sent by client to service as first message. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_JOIN 520 + +/** + * Insert an element. Sent by client to service. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT 521 + +/** + * Begin accepting new elements from other participants. + * Sent by client to service. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_BEGIN 522 + +/** + * Sent by service when a new element is added. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT 523 + +/** + * Sent by client to service in order to start the consensus conclusion. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE 524 + +/** + * Sent by service to client in order to signal a completed consensus + * conclusion. Last message sent in a consensus session. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE 525 + + +/* message types 526-539 reserved for consensus client/service messages */ + + +/** + * Sent by client to service, telling whether a received element should + * be accepted and propagated further or not. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_ACK 540 + +/** + * Strata estimator. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_DELTA_ESTIMATE 541 + +/** + * IBF containing all elements of a peer. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_DIFFERENCE_DIGEST 542 + +/** + * One or more elements that are sent from peer to peer. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_ELEMENTS 543 + +/** + * Elements, and requests for further elements + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_ELEMENTS_REQUEST 544 + +/** + * Elements that a peer reports to be missing at the remote peer. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_ELEMENTS_REPORT 545 + +/** + * Provide context for a consensus round. + */ +#define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_ROUND_CONTEXT 547 + + +/******************************************************************************* + * SETU message types + ******************************************************************************/ + + +/** + * Cancel a set operation + */ +#define GNUNET_MESSAGE_TYPE_SETU_CANCEL 550 + +/** + * Add element to set + */ +#define GNUNET_MESSAGE_TYPE_SETU_ADD 551 + +/** + * Create a new local set + */ +#define GNUNET_MESSAGE_TYPE_SETU_CREATE 552 + +/** + * Handle result message from operation + */ +#define GNUNET_MESSAGE_TYPE_SETU_RESULT 553 + +/** + * Evaluate a set operation + */ +#define GNUNET_MESSAGE_TYPE_SETU_EVALUATE 554 + +/** + * Listen for operation requests + */ +#define GNUNET_MESSAGE_TYPE_SETU_LISTEN 555 + +/** + * Reject a set request. + */ +#define GNUNET_MESSAGE_TYPE_SETU_REJECT 556 + +/** + * Accept an incoming set request + */ +#define GNUNET_MESSAGE_TYPE_SETU_ACCEPT 557 + +/** + * Notify the client of an incoming request from a remote peer + */ +#define GNUNET_MESSAGE_TYPE_SETU_REQUEST 558 + + +/** + * Demand the whole element from the other + * peer, given only the hash code. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_REQUEST_FULL 559 + +/** + * Demand the whole element from the other + * peer, given only the hash code. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND 560 + +/** + * Tell the other peer to send us a list of + * hashes that match an IBF key. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_INQUIRY 561 + +/** + * Tell the other peer which hashes match a + * given IBF key. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_OFFER 562 + +/** + * Request a set union operation from a remote peer. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST 563 + +/** + * Strata estimator. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_SE 564 + +/** + * Invertible bloom filter. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_IBF 565 + +/** + * Actual set elements. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS 566 + +/** + * Set operation is done. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_DONE 568 + +/** + * Compressed strata estimator. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_SEC 569 + +/** + * Request all missing elements from the other peer, + * based on their sets and the elements we previously sent + * with #GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_DONE 570 + +/** + * Send a set element, not as response to a demand but because + * we're sending the full set. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_FULL_ELEMENT 571 + +/** + * Request all missing elements from the other peer, + * based on their sets and the elements we previously sent + * with #GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS. + */ +#define GNUNET_MESSAGE_TYPE_SETU_P2P_OVER 572 + +/** + * Signals other peer that all elements are sent. + */ + +#define GNUNET_MESSAGE_TYPE_SETU_P2P_SEND_FULL 710 + + +/******************************************************************************* + * SETI message types + ******************************************************************************/ + + +/** + * Cancel a set operation + */ +#define GNUNET_MESSAGE_TYPE_SETI_CANCEL 580 + +/** + * Add element to set. + */ +#define GNUNET_MESSAGE_TYPE_SETI_ADD 581 + +/** + * Create a new local set + */ +#define GNUNET_MESSAGE_TYPE_SETI_CREATE 582 + +/** + * Handle result message from operation + */ +#define GNUNET_MESSAGE_TYPE_SETI_RESULT 583 + +/** + * Evaluate a set operation + */ +#define GNUNET_MESSAGE_TYPE_SETI_EVALUATE 584 + +/** + * Listen for operation requests + */ +#define GNUNET_MESSAGE_TYPE_SETI_LISTEN 585 + +/** + * Reject a set request. + */ +#define GNUNET_MESSAGE_TYPE_SETI_REJECT 586 + +/** + * Accept an incoming set request + */ +#define GNUNET_MESSAGE_TYPE_SETI_ACCEPT 587 + +/** + * Notify the client of an incoming request from a remote peer + */ +#define GNUNET_MESSAGE_TYPE_SETI_REQUEST 588 + +/** + * Information about the element count for intersection + */ +#define GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO 591 + +/** + * Bloom filter message for intersection exchange started by Bob. + */ +#define GNUNET_MESSAGE_TYPE_SETI_P2P_BF 592 + +/** + * Intersection operation is done. + */ +#define GNUNET_MESSAGE_TYPE_SETI_P2P_DONE 593 + +/** + * Request to begin set intersection operation. + */ +#define GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST 594 + + +/******************************************************************************* + * SET message types + ******************************************************************************/ + + +/** + * Demand the whole element from the other + * peer, given only the hash code. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL 565 + +/** + * Demand the whole element from the other + * peer, given only the hash code. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND 566 + +/** + * Tell the other peer to send us a list of + * hashes that match an IBF key. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY 567 + +/** + * Tell the other peer which hashes match a + * given IBF key. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OFFER 568 + +/** + * Reject a set request. + */ +#define GNUNET_MESSAGE_TYPE_SET_REJECT 569 + +/** + * Cancel a set operation + */ +#define GNUNET_MESSAGE_TYPE_SET_CANCEL 570 + +/** + * Acknowledge result from iteration + */ +#define GNUNET_MESSAGE_TYPE_SET_ITER_ACK 571 + +/** + * Create an empty set + */ +#define GNUNET_MESSAGE_TYPE_SET_RESULT 572 + +/** + * Add element to set + */ +#define GNUNET_MESSAGE_TYPE_SET_ADD 573 + +/** + * Remove element from set + */ +#define GNUNET_MESSAGE_TYPE_SET_REMOVE 574 + +/** + * Listen for operation requests + */ +#define GNUNET_MESSAGE_TYPE_SET_LISTEN 575 + +/** + * Accept a set request + */ +#define GNUNET_MESSAGE_TYPE_SET_ACCEPT 576 + +/** + * Evaluate a set operation + */ +#define GNUNET_MESSAGE_TYPE_SET_EVALUATE 577 + +/** + * Start a set operation with the given set + */ +#define GNUNET_MESSAGE_TYPE_SET_CONCLUDE 578 + +/** + * Notify the client of a request from a remote peer + */ +#define GNUNET_MESSAGE_TYPE_SET_REQUEST 579 + +/** + * Create a new local set + */ +#define GNUNET_MESSAGE_TYPE_SET_CREATE 580 + +/** + * Request a set operation from a remote peer. + */ +#define GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST 581 + +/** + * Strata estimator. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE 582 + +/** + * Invertible bloom filter. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF 583 + +/** + * Actual set elements. + */ +#define GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS 584 + +/** + * Set operation is done. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE 586 + +/** + * Start iteration over set elements. + */ +#define GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST 587 + +/** + * Element result for the iterating client. + */ +#define GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT 588 + +/** + * Iteration end marker for the client. + */ +#define GNUNET_MESSAGE_TYPE_SET_ITER_DONE 589 + +/** + * Compressed strata estimator. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC 590 + +/** + * Information about the element count for intersection + */ +#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO 591 + +/** + * Bloom filter message for intersection exchange started by Bob. + */ +#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF 592 + +/** + * Intersection operation is done. + */ +#define GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE 593 + +/** + * Ask the set service to prepare a copy of a set. + */ +#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE 594 + +/** + * Give the client an ID for connecting to the set's copy. + */ +#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE 595 + +/** + * Sent by the client to the server to connect to an existing, + * lazily copied set. + */ +#define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT 596 + +/** + * Request all missing elements from the other peer, + * based on their sets and the elements we previously sent + * with #GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE 597 + +/** + * Send a set element, not as response to a demand but because + * we're sending the full set. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT 598 + +/** + * Request all missing elements from the other peer, + * based on their sets and the elements we previously sent + * with #GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS. + */ +#define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER 599 + + +/******************************************************************************* + * TESTBED LOGGER message types + ******************************************************************************/ + +/** + * Message for TESTBED LOGGER + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG 600 + +/** + * Message for TESTBED LOGGER acknowledgement + */ +#define GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_ACK 601 + + +/** + * Advertise regex capability. + */ +#define GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE 620 + +/** + * Search for peer with matching capability. + */ +#define GNUNET_MESSAGE_TYPE_REGEX_SEARCH 621 + +/** + * Result in response to regex search. + */ +#define GNUNET_MESSAGE_TYPE_REGEX_RESULT 622 + +/******************************************************************************* + * IDENTITY message types + ******************************************************************************/ + +/** + * First message send from identity client to service (to subscribe to + * updates). + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_START 624 + +/** + * Generic response from identity service with success and/or error message. + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE 625 + +/** + * Update about identity status from service to clients. + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE 626 + +/** + * Client requests to know default identity for a subsystem. + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT 627 + +/** + * Client sets default identity; or service informs about default identity. + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT 628 + +/** + * Create new identity (client->service). + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_CREATE 629 + +/** + * Rename existing identity (client->service). + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_RENAME 630 + +/** + * Delete identity (client->service). + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_DELETE 631 + +/** + * First message send from identity client to service to + * lookup a single ego. The service will respond with a + * #GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE message if the ego + * exists, or a #GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE if not. + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP 632 + +/** + * First message send from identity client to service to lookup a + * single ego matching the given suffix (longest match). The service + * will respond with a #GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE message if + * the ego exists, or a #GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE if + * not. + */ +#define GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP_BY_SUFFIX 633 + + +/******************************************************************************* + * REVOCATION message types + ******************************************************************************/ + +/** + * Client to service: was this key revoked? + */ +#define GNUNET_MESSAGE_TYPE_REVOCATION_QUERY 636 + +/** + * Service to client: answer if key was revoked! + */ +#define GNUNET_MESSAGE_TYPE_REVOCATION_QUERY_RESPONSE 637 + +/** + * Client to service OR peer-to-peer: revoke this key! + */ +#define GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE 638 + +/** + * Service to client: revocation confirmed + */ +#define GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE_RESPONSE 639 + + +/******************************************************************************* + * SCALARPRODUCT message types + ******************************************************************************/ + +/** + * Client -> Alice + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE 640 + +/** + * Client -> Bob + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB 641 + +/** + * Client -> Alice multipart + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_ALICE 642 + +/** + * Client -> Bob multipart + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_BOB 643 + +/** + * Alice -> Bob session initialization + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION 644 + +/** + * Alice -> Bob SP crypto-data (after intersection) + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA 645 + +/** + * Bob -> Alice SP crypto-data + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA 647 + +/** + * Bob -> Alice SP crypto-data multipart + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART 648 + +/** + * Alice/Bob -> Client Result + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT 649 + +/** + * Alice -> Bob ECC session initialization + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION 650 + +/** + * Alice -> Bob ECC crypto data + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA 651 + +/** + * Bob -> Alice ECC crypto data + */ +#define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA 652 + + +/******************************************************************************* + * PSYCSTORE message types + ******************************************************************************/ + +/** + * Store a membership event. + */ +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_STORE 660 + +/** + * Test for membership of a member at a particular point in time. + */ +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_TEST 661 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_FRAGMENT_STORE 662 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_FRAGMENT_GET 663 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_MESSAGE_GET 664 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_MESSAGE_GET_FRAGMENT 665 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_COUNTERS_GET 666 + +/* 657 */ + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_MODIFY 668 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_SYNC 669 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_RESET 670 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_HASH_UPDATE 671 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_GET 672 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_GET_PREFIX 673 + +/** + * Generic response from PSYCstore service with success and/or error message. + */ +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE 674 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_FRAGMENT 675 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_COUNTERS 676 + +#define GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_STATE 677 + + +/******************************************************************************* + * PSYC message types + ******************************************************************************/ + +/** + * C: client + * S: service + * M: multicast + */ + +/** S->C: result of an operation */ +#define GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE 680 + +/** C->S: request to start a channel as a master */ +#define GNUNET_MESSAGE_TYPE_PSYC_MASTER_START 681 + +/** S->C: master start acknowledgement */ +#define GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK 682 + +/** C->S: request to join a channel as a slave */ +#define GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN 683 + +/** S->C: slave join acknowledgement */ +#define GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK 684 + +/** C->S: request to part from a channel */ +#define GNUNET_MESSAGE_TYPE_PSYC_PART_REQUEST 685 + +/** S->C: acknowledgement that a slave of master parted from a channel */ +#define GNUNET_MESSAGE_TYPE_PSYC_PART_ACK 686 + +/** M->S->C: incoming join request from multicast */ +#define GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST 687 + +/** C->S->M: decision about a join request */ +#define GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION 688 + + +/** C->S: request to add/remove channel slave in the membership database. */ +#define GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_MEMBERSHIP_STORE 689 + +/* 690 */ + +/** S<--C: PSYC message which contains one or more message parts. */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE 691 + +/** M<->S<->C: PSYC message which contains a header and one or more message + * parts. */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER \ + 692 // FIXME: start using this where appropriate + +/** Message part: method */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD 693 + +/** Message part: modifier */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER 694 + +/** Message part: modifier continuation */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT 695 + +/** Message part: data */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA 696 + +/** Message part: end of message */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END 697 + +/** Message part: message cancelled */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL 698 + +/** S->C: message acknowledgement */ +#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_ACK 699 + +/* 700 */ + +/** C->S: request channel history replay from PSYCstore. */ +#define GNUNET_MESSAGE_TYPE_PSYC_HISTORY_REPLAY 701 + +/** S->C: result for a channel history request */ +#define GNUNET_MESSAGE_TYPE_PSYC_HISTORY_RESULT 702 + + +/** C->S: request best matching state variable from PSYCstore. */ +#define GNUNET_MESSAGE_TYPE_PSYC_STATE_GET 703 + +/** C->S: request state variables with a given prefix from PSYCstore. */ +#define GNUNET_MESSAGE_TYPE_PSYC_STATE_GET_PREFIX 704 + +/** S->C: result for a state request. */ +#define GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT 705 + + +/******************************************************************************* + * CONVERSATION message types + ******************************************************************************/ + +/** + * Message to transmit the audio between helper and speaker/microphone library. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO 730 + +/** + * Client -> Server message to register a phone. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_REGISTER 731 + +/** + * Client -> Server message to reject/hangup a call + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP 732 + +/** + * Client -> Server message to reject/hangup a call + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP 733 + +/** + * Client <- Server message to indicate a ringing phone + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_CALL 734 + +/** + * Client <- Server message to indicate a ringing phone + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING 735 + +/** + * Client <-> Server message to suspend connection. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND 736 + +/** + * Client <-> Server message to resume connection. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME 737 + +/** + * Service -> Client message to notify that phone was picked up. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP 738 + +/** + * Client <-> Server message to send audio data. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO 739 + +/** + * Cadet: call initiation + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING 740 + +/** + * Cadet: hang up / refuse call + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_HANG_UP 741 + +/** + * Cadet: pick up phone (establish audio channel) + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_PICK_UP 742 + +/** + * Cadet: phone suspended. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_SUSPEND 743 + +/** + * Cadet: phone resumed. + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RESUME 744 + +/** + * Cadet: audio data + */ +#define GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_AUDIO 745 + + +/******************************************************************************* + * MULTICAST message types + ******************************************************************************/ + +/** + * C: client + * S: service + * T: cadet + */ + +/** + * C->S: Start the origin. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START 750 + +/** + * C->S: Join group as a member. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN 751 + +/** + * C<--S<->T: A peer wants to join the group. + * + * Unicast message to the origin or another group member. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST 752 + +/** + * C<->S<->T: Response to a join request. + * + * Unicast message from a group member to the peer wanting to join. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION 753 + +/** + * A peer wants to part the group. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_PART_REQUEST 754 + +/** + * Acknowledgement sent in response to a part request. + * + * Unicast message from a group member to the peer wanting to part. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_PART_ACK 755 + +// FIXME: this is never used! +/** + * Group terminated. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_GROUP_END 756 + +/** + * C<->S<->T: Multicast message from the origin to all members. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE 757 + +/** + * C<->S<->T: Unicast request from a group member to the origin. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST 758 + +/** + * C->S: Acknowledgement of a message or request fragment for the client. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_FRAGMENT_ACK 759 + +/** + * C<->S<->T: Replay request from a group member to another member. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST 760 + +/** + * C<->S<->T: Replay response from a group member to another member. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE 761 + +/** + * C<->S: End of replay response. + */ +#define GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END 762 + + +/******************************************************************************* + * SECRETSHARING message types + ******************************************************************************/ + + +/** + * Establish a new session. + */ +#define GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_GENERATE 780 + +/** + * Request the decryption of a ciphertext. + */ +#define GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT 781 + +/** + * The service succeeded in decrypting a ciphertext. + */ +#define GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_DECRYPT_DONE 782 + +/** + * The cryptosystem has been established. + * Contains the peer's share. + */ +#define GNUNET_MESSAGE_TYPE_SECRETSHARING_CLIENT_SECRET_READY 783 + + +/******************************************************************************* + * PEERSTORE message types + ******************************************************************************/ + +/** + * Store request message + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_STORE 820 + +/** + * Iteration request (see also 828, 829) + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_START 821 + +/** + * Record result message + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_RECORD 822 + +/** + * Iteration end message + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END 823 + +/** + * Monitor request + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_START 824 + +/** + * Monitor sync + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_SYNC 825 + +/** + * Monitor next request + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_NEXT 826 + +/** + * Store result message + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT 827 + +/** + * Iteration request (see also 821, 829) + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_NEXT 828 + +/** + * Iteration request (see also 821, 828) + */ +#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_STOP 829 + +/******************************************************************************* + * SOCIAL message types + ******************************************************************************/ + +/** + * C: client + * S: service + * P: PSYC + */ + +/** S->C: result of an operation */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_RESULT_CODE 840 + +/** C->S: request to enter a place as the host */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER 841 + +/** S->C: host enter acknowledgement */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_HOST_ENTER_ACK 842 + +/** C->S: request to enter a place as a guest */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER 843 + +/** C->S: request to enter a place as a guest, using a GNS address */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_BY_NAME 844 + +/** S->C: guest enter acknowledgement */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_GUEST_ENTER_ACK 845 + +/** P->S->C: incoming entry request from PSYC */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_ENTRY_REQUEST 846 + +/** C->S->P: decision about an entry request */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_ENTRY_DECISION 847 + +/** C->S: request to leave a place */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE 848 + +/** S->C: place leave acknowledgement */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_PLACE_LEAVE_ACK 849 + +/** C->S: add place to GNS zone */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_PLACE 850 + +/** C->S: add nym to GNS zone */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_ZONE_ADD_NYM 851 + +/** C->S: connect application */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_CONNECT 852 + +/** C->S: detach a place from application */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_DETACH 853 + +/** S->C: notify about an existing ego */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO 854 + +/** S->C: end of ego list */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_EGO_END 855 + +/** S->C: notify about an existing place */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE 856 + +/** S->C: end of place list */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_APP_PLACE_END 857 + +/** C->S: set message processing flags */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_SET 858 + +/** C->S: clear message processing flags */ +#define GNUNET_MESSAGE_TYPE_SOCIAL_MSG_PROC_CLEAR 859 + +/******************************************************************************* + * X-VINE DHT messages + ******************************************************************************/ + +/** + * Trail setup request is received by a peer. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP 880 + +/** + * Trail to a particular peer is returned to this peer. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT 881 + +/** + * Verify if your immediate successor is still your immediate successor. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR 882 + +/** + * Notify your new immediate successor that you are its new predecessor. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR 883 + +/** + * Message which contains the immediate predecessor of requested successor + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT 884 + +/** + * Message which contains the get result. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT 885 + +/** + * Trail Rejection Message. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION 886 + +/** + * Trail Tear down Message. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN 887 + +/** + * Routing table add message. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL 888 + +/** + * Peer is storing the data in DHT. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT 890 + +/** + * Peer tries to find data in DHT. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_GET 891 + +/** + * Send back peer that considers you are its successor, a confirmation + * that you got the notify successor message. + */ +#define GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION 892 + + +/******************************************************************************* + * Whanau DHT messages + ******************************************************************************/ + + +/** + * This message contains the query for performing a random walk + */ +#define GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK 910 + +/** + * This message contains the result of a random walk + */ +#define GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE 911 + +/** + * This message contains a notification for the death of a trail + */ +#define GNUNET_MESSAGE_TYPE_WDHT_TRAIL_DESTROY 912 + +/** + * This message are used to route a query to a peer + */ +#define GNUNET_MESSAGE_TYPE_WDHT_TRAIL_ROUTE 913 + +/** + * This message contains the query to transfer successor values. + */ +#define GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND 914 + +/** + * Message which contains the get query + */ +#define GNUNET_MESSAGE_TYPE_WDHT_GET 915 + +/** + * Message which contains the "put", a response to + * #GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND. + */ +#define GNUNET_MESSAGE_TYPE_WDHT_PUT 916 + +/** + * Message which contains the get result, a response + * to #GNUNET_MESSAGE_TYPE_WDHT_GET. + */ +#define GNUNET_MESSAGE_TYPE_WDHT_GET_RESULT 917 + + +/******************************************************************************* + * RPS messages + ******************************************************************************/ + +/* P2P Messages */ + +/** + * RPS check liveliness message to check liveliness of other peer + */ +#define GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE 950 + +/** + * RPS PUSH message to push own ID to another peer + */ +#define GNUNET_MESSAGE_TYPE_RPS_PP_PUSH 951 + +/** + * RPS PULL REQUEST message to request the local view of another peer + */ +#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST 952 + +/** + * RPS PULL REPLY message which contains the view of the other peer + */ +#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY 953 + + +/* Client-Service Messages */ + + +/** + * RPS CS SEED Message for the Client to seed peers into rps + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_SEED 954 + +#ifndef ENABLE_MALICIOUS +#define ENABLE_MALICIOUS 0 +#endif + +#if ENABLE_MALICIOUS +/** + * Turn RPS service malicious + */ +#define GNUNET_MESSAGE_TYPE_RPS_ACT_MALICIOUS 955 + +#endif /* ENABLE_MALICIOUS */ + +/** + * RPS client-service message to start a sub sampler + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_SUB_START 956 + +/** + * RPS client-service message to stop a sub sampler + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_SUB_STOP 957 + +/* Debugging API continues at 1130 */ + +/******************************************************************************/ + + +/************************************************** + * + * IDENTITY PROVIDER MESSAGE TYPES + */ +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE 961 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE 962 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START 963 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP 964 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT 965 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT 966 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET 967 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT 968 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET 969 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT 970 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET 971 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT 972 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START 973 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP 974 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT 975 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE 976 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE 977 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE 978 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_RESULT 979 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START 980 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP 981 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT 982 + + +/************************************************** + * + * ABD MESSAGE TYPES + */ +#define GNUNET_MESSAGE_TYPE_ABD_VERIFY 991 + +#define GNUNET_MESSAGE_TYPE_ABD_VERIFY_RESULT 992 + +#define GNUNET_MESSAGE_TYPE_ABD_COLLECT 993 + +#define GNUNET_MESSAGE_TYPE_ABD_COLLECT_RESULT 994 + +#define GNUNET_MESSAGE_TYPE_ABD_INTERMEDIATE_RESULT 995 + +/******************************************************************************/ + + +/******************************************************************************/ +/*********************************** CADET **********************************/ +/******************************************************************************/ +/* CADET: message types 1000-1059 + * 1000-1009 Connection-level Messages + * 1010-1019 Channel-level Messages + * 1020-1029 Local Client-Service + * 1030-1049 Local Service Monitoring + * 1050-1059 Application Data + */ + +/******************************** Connection ********************************/ + +/** + * Request the creation of a connection + */ +#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE 1000 + +/** + * Send origin an ACK that the connection is complete + */ +#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK 1001 + +/** + * Notify that a connection is no longer valid + */ +#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN 1002 + +/** + * Request the destruction of a connection + */ +#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY 1003 + +/** + * At some point, the route will spontaneously change TODO + */ +#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_PATH_CHANGED_UNIMPLEMENTED 1004 + +/** + * Hop-by-hop, connection dependent ACK. + * + * @deprecated + */ +#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK 1005 + +/** + * We do not bother with ACKs for + * #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED messages, but we instead + * poll for one if we got nothing for a while and start to be worried. + * + * @deprecated + */ +#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL 1006 + +/** + * Axolotl key exchange. + */ +#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX 1007 + +/** + * Axolotl encrypted data. + */ +#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED 1008 + +/** + * Axolotl key exchange response with authentication. + */ +#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH 1009 + + +/********************************** Channel *********************************/ + +/** + * Payload data (inside an encrypted tunnel). + */ +#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA 1010 + +/** + * Confirm payload data end-to-end. + */ +#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK 1011 + +/** + * Announce connection is still alive (direction sensitive). + */ +#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE 1012 + +/** + * Ask the cadet service to create a new channel. + */ +#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN 1013 + +/** + * Ask the cadet service to destroy a channel. + */ +#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY 1014 + +/** + * Confirm the creation of a channel + */ +#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK 1015 + +/** + * Reject the creation of a channel + * + * @deprecated + */ +#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED 1016 + +/*********************************** Local **********************************/ + +/** + * Payload client <-> service + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA 1020 + +/** + * Local ACK for data. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK 1021 + +/** + * Start listening on a port. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN 1022 + +/** + * Stop listening on a port. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE 1023 + +/** + * Ask the cadet service to create a new channel. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE 1024 + +/** + * Tell client that a channel was destroyed. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY 1025 + +/********************************** Monitor *********************************/ + + +/** + * Local information about all channels of service. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_CHANNEL 1030 + +/** + * Local information of service about a specific channel. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL 1031 + +/** + * End of local information of service about channels. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL_END 1032 + +/** + * Request local information about all peers known to the service. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS 1033 + +/** + * Local information about all peers known to the service. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS 1034 + +/** + * End of local information about all peers known to the service. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS_END 1035 + +/** + * Request local information of service about paths to specific peer. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH 1036 + +/** + * Local information of service about a specific path. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH 1037 + +/** + * End of local information of service about a specific path. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH_END 1038 + +/** + * Request local information about all tunnels of service. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS 1039 + +/** + * Local information about all tunnels of service. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS 1040 + +/** + * End of local information about all tunnels of service. + */ +#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS_END 1041 + +/** + * Request to drop a message of type X to peer y. + */ +#define GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE 1042 + + +/******************************** Application *******************************/ + +/** + * Traffic (net-cat style) used by the Command Line Interface. + */ +#define GNUNET_MESSAGE_TYPE_CADET_CLI 1059 + +/******************************************************************************/ + + +/******************************************************************************/ +/************************************* NAT **********************************/ +/******************************************************************************/ + +/** + * Message to ask NAT service to register a client. + */ +#define GNUNET_MESSAGE_TYPE_NAT_REGISTER 1060 + +/** + * Message to ask NAT service to handle a STUN packet. + */ +#define GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN 1061 + +/** + * Message to ask NAT service to request connection reversal. + */ +#define GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL 1062 + +/** + * Message to from NAT service notifying us that connection reversal + * was requested by another peer. + */ +#define GNUNET_MESSAGE_TYPE_NAT_CONNECTION_REVERSAL_REQUESTED 1063 + +/** + * Message to from NAT service notifying us that one of our + * addresses changed. + */ +#define GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE 1064 + +/** + * Message to ask NAT service to notify all clients about a new global address. + */ +#define GNUNET_MESSAGE_TYPE_NAT_ADD_GLOBAL_ADDRESS 1065 + +/** + * Message to ask NAT service to request autoconfiguration. + */ +#define GNUNET_MESSAGE_TYPE_NAT_AUTO_REQUEST_CFG 1067 + +/** + * Message from NAT service with the autoconfiguration result. + */ +#define GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT 1068 + + +/* 1080-1109 reserved for TMCG (Heiko Stamer, see gnunet-developers, January + * 2017) */ + + +/******************************************************************************/ +/*********************************** AUCTION ********************************/ +/******************************************************************************/ + +/** + * Client wants to create a new auction. + */ +#define GNUNET_MESSAGE_TYPE_AUCTION_CLIENT_CREATE 1110 + +/** + * Client wants to join an existing auction. + */ +#define GNUNET_MESSAGE_TYPE_AUCTION_CLIENT_JOIN 1111 + +/** + * Service reports the auction outcome to the client. + */ +#define GNUNET_MESSAGE_TYPE_AUCTION_CLIENT_OUTCOME 1112 + + +/******************************************************************************/ +/********************************* RPS DEBUG ********************************/ +/******************************************************************************/ + +/** + * @brief Request updates of the view + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REQUEST 1130 + +/** + * @brief Send update of the view + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REPLY 1131 + +/** + * @brief Cancel getting updates of the view + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_CANCEL 1132 + + +/** + * @brief Request biased input stream + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_REQUEST 1133 + +/** + * @brief Send peer of biased stream + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_REPLY 1134 + +/** + * @brief Cancel getting biased stream + */ +#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_CANCEL 1135 + + +/******************************************************* + NEW (TNG) Transport service + ******************************************************* */ + +/** + * @brief inform transport to add an address of this peer + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS 1200 + +/** + * @brief inform transport to delete an address of this peer + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS 1201 + +/** + * @brief inform transport about an incoming message + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG 1202 + +/** + * @brief transport acknowledges processing an incoming message + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK 1203 + +/** + * @brief inform transport that a queue was setup to talk to some peer + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP 1204 + +/** + * @brief inform transport that a queue was torn down + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN 1205 + +/** + * @brief transport tells communicator it wants a queue + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE 1206 + +/** + * Response from communicator: will try to create queue. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK 1207 + +/** + * Response from communicator: address bogus, will not try to create queue. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL 1208 + +/** + * @brief transport tells communicator it wants to transmit + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG 1209 + +/** + * @brief communicator tells transports that message was sent + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK 1210 + +/** + * Message sent to indicate to the transport which address + * prefix is supported by a communicator. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR 1211 + +/** + * Tell transport that it should assist with exchanging a + * message between communicators. Usually used when + * communciators are uni-directional and need an alternative + * back-channel. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL 1212 + +/** + * Message type used between transport services when they + * internally forward communicator backchannel messages. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION 1213 + +/** + * Type of a fragment of a CORE message created by transport to adjust + * message length to a queue's MTU. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT 1214 + +/** + * Wrapper around non-fragmented CORE message used to measure RTT + * and ensure reliability. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX 1216 + +/** + * Confirmation for a #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK 1217 + +/** + * Message sent for topology discovery at transport level. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN 1218 + +/** + * Source-routed transport message based DV information gathered. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX 1219 + +/** + * Transport signalling incoming backchannel message to a communicator. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING 1220 + +/** + * Transport signalling incoming backchannel message to a communicator. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL 1221 + +/** + * @brief inform transport that a queue was updated + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_UPDATE 1222 + +/** + * Message sent to indicate to the transport that a monitor + * wants to observe certain events. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_START 1250 + +/** + * Message sent to indicate to a monitor about events. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_DATA 1251 + +/** + * Message sent to indicate to a monitor that a one-shot + * iteration over events is done. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_END 1252 + +/** + * Message exchanged between communicators to confirm + * successful KX (and address validation). + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_KX_CONFIRMATION 1275 + +/** + * Message exchanged between communicators to exchange + * flow control (FC) limits and acknowledgemets. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_FC_LIMITS 1276 + +/** + * Type of the 'struct ExpressPreferenceMessage' send by clients to TRANSPORT + * to establish bandwidth preference. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST 1300 + +/** + * Type of the 'struct ExpressPreferenceMessage' send by clients to TRANSPORT + * to abandon bandwidth preference. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL 1301 + +/** + * Type of the 'struct RequestHelloValidationMessage' send by clients to + * TRANSPORT to trigger validation of addresses. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION 1302 + + +/** + * P2P message: transport requests confirmation that an address works. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE 1303 + +/** + * P2P message: transport proves that an address worked. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE 1304 + + +/* ************** NEW (NG) ATS Messages ************* */ +/* NOTE: it is not clear ATS will survive in TNG */ + +/** + * Type of the 'struct ExpressPreferenceMessage' send by clients to ATS + * to establish bandwidth preference. + */ +#define GNUNET_MESSAGE_TYPE_ATS_SUGGEST 1400 + +/** + * Type of the 'struct ExpressPreferenceMessage' send by clients to ATS + * to abandon bandwidth preference. + */ +#define GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL 1401 + + +/** + * Type of the 'struct SessionAddMessage' send by transport clients to ATS + * to ask ATS to allocate resources to a session. + */ +#define GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD 1402 + +/** + * Type of the 'struct SessionAddMessage' send by transport clients to ATS + * to inform ATS about a session where resources are consumed but allocation + * is impossible (unidirectional). + */ +#define GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY 1403 + +/** + * Type of the 'struct SessionUpdateMessage' send by transport clients to ATS + * to inform ATS about property changes of a session. + */ +#define GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE 1404 + +/** + * Type of the 'struct SessionDelMessage' send by transport clients to ATS + * to tell ATS that a session is no longer available. + */ +#define GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL 1405 + +/** + * Type of the 'struct SessionAllocationMessage' send by ATS to the + * transport to tell it about resources to allocate to the session. + */ +#define GNUNET_MESSAGE_TYPE_ATS_SESSION_ALLOCATION 1406 + + +/** + * TCP communicator rekey message. + */ +#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY 1450 + +/** + * TCP communicator payload box + */ +#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX 1451 + +/** + * TCP communicator end of stream. + */ +#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH 1452 + +/** + * TCP communicator confirmation ack. + */ +#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK 1453 + +/** + * UDP KX acknowledgement. + */ +#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK 1460 + +/** + * UDP communicator padding. + */ +#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD 1461 + +/** + * UDP Rekey. + */ +#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY 1462 + +/** + * Next available: 1500 + */ +#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE 1500 + +#define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT 1501 + + +/*********************************************************************************/ +/********************************** MESSENGER **********************************/ +/*********************************************************************************/ +/* MESSENGER: message types 1600-1629 + * 1600-1609 Connection-level Messages + * 1610-1619 Room-level Messages + */ + +/********************************* Connection **********************************/ + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE 1600 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY 1601 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID 1602 + +/************************************ Room *************************************/ + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN 1610 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY 1611 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE 1612 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE 1614 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE 1615 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE 1616 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SYNC 1617 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_LINK 1618 + +/*********************************************************************************/ + +/*********************************************************************************/ +/********************************** Cmd Testing **********************************/ +/*********************************************************************************/ + +/** + * The initialization message towards gnunet-cmds-helper + */ +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT 1700 + +/** + * The reply message from gnunet-cmds-helper + */ +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY 1701 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED 1702 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED 1703 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_TEST_PREPARED 1704 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_LOCAL_TESTS_PREPARED 1705 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED 1706 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_REACHED 1707 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACH 1708 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_CROSSABLE 1709 + +#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_BARRIER_ATTACHED 1710 + +/*********************************************************************************/ + +/*********************************************************************************/ +/********************************** NAMESTORE (cont.) **************************/ +/*********************************************************************************/ +/* NAMESTORE: message types 1750-1800 + */ + +/** + * Message type for start of record edit with advisory lock + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT 1750 + +/** + * Return record set to edit with previous editor hint/advisory lock + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_RESPONSE 1751 + +/** + * Message type for cancellation/reset of editor hint/advisory lock + */ +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_CANCEL 1752 + +/** + * Type used to match 'all' message types. + */ +#define GNUNET_MESSAGE_TYPE_ALL 65535 + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_PROTOCOLS_H */ +#endif + +/** @} */ /* end of group protocols */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_protocols.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_scheduler_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_scheduler_lib.h @@ -0,0 +1,938 @@ +/* + This file is part of GNUnet + Copyright (C) 2009-2016 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 + * API to schedule computations using continuation passing style + * + * @defgroup scheduler Scheduler library + * Event loop (scheduler) + * + * Schedule computations using continuation passing style. + * + * @{ + */ + +#ifndef GNUNET_SCHEDULER_LIB_H +#define GNUNET_SCHEDULER_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * Opaque reference to a task. + */ +struct GNUNET_SCHEDULER_Task; + +/** + * Reasons why the schedule may have triggered + * the task now. + */ +enum GNUNET_SCHEDULER_Reason +{ + /** + * This task is not ready. + */ + GNUNET_SCHEDULER_REASON_NONE = 0, + + /** + * This is the very first task run during startup. + */ + GNUNET_SCHEDULER_REASON_STARTUP = 1, + + /** + * We are shutting down and are running all shutdown-related tasks. + */ + GNUNET_SCHEDULER_REASON_SHUTDOWN = 2, + + /** + * The specified timeout has expired. + * (also set if the delay given was 0). + */ + GNUNET_SCHEDULER_REASON_TIMEOUT = 4, + + /** + * The reading socket is ready. + */ + GNUNET_SCHEDULER_REASON_READ_READY = 8, + + /** + * The writing socket is ready. + */ + GNUNET_SCHEDULER_REASON_WRITE_READY = 16, + + /** + * The prerequisite task is done. + */ + GNUNET_SCHEDULER_REASON_PREREQ_DONE = 32 +}; + + + +#include "gnunet_time_lib.h" +#include "gnunet_network_lib.h" + + +/** + * Possible events on FDs, used as a bitmask. + * Modelled after GPollFD. + */ +enum GNUNET_SCHEDULER_EventType +{ + /** + * No event (useful for timeout). + */ + GNUNET_SCHEDULER_ET_NONE = 0, + + /** + * Data available for reading. + */ + GNUNET_SCHEDULER_ET_IN = 1, + + /** + * Buffer available for writing. + */ + GNUNET_SCHEDULER_ET_OUT = 2, + + /** + * + */ + GNUNET_SCHEDULER_ET_HUP = 4, + + /** + * + */ + GNUNET_SCHEDULER_ET_ERR = 8, + + /** + * + */ + GNUNET_SCHEDULER_ET_PRI = 16, + + /** + * + */ + GNUNET_SCHEDULER_ET_NVAL = 32 +}; + + +/** + * Information about an event relating to a file descriptor/socket. + */ +struct GNUNET_SCHEDULER_FdInfo +{ + /** + * GNUnet network socket the event is about, matches @a sock, + * NULL if this is about a file handle or if no network + * handle was given to the scheduler originally. + */ + const struct GNUNET_NETWORK_Handle *fd; + + /** + * GNUnet file handle the event is about, matches @a sock, + * NULL if this is about a network socket or if no network + * handle was given to the scheduler originally. + */ + const struct GNUNET_DISK_FileHandle *fh; + + /** + * Type of the event that was generated related to @e sock. + */ + enum GNUNET_SCHEDULER_EventType et; + + /** + * Underlying OS handle the event was about. + */ + int sock; +}; + + +/** + * Context information passed to each scheduler task. + */ +struct GNUNET_SCHEDULER_TaskContext +{ + /** + * Reason why the task is run now + */ + enum GNUNET_SCHEDULER_Reason reason; + + /** + * Length of the following array. + */ + unsigned int fds_len; + + /** + * Array of length @e fds_len with information about ready FDs. + * Note that we use the same format regardless of the internal + * event loop that was used. The given array should only contain + * information about file descriptors relevant to the current task. + */ + const struct GNUNET_SCHEDULER_FdInfo *fds; + + /** + * Set of file descriptors ready for reading; note that additional + * bits may be set that were not in the original request. + * @deprecated + */ + const struct GNUNET_NETWORK_FDSet *read_ready; + + /** + * Set of file descriptors ready for writing; note that additional + * bits may be set that were not in the original request. + * @deprecated + */ + const struct GNUNET_NETWORK_FDSet *write_ready; +}; + + +/** + * Function used by event-loop implementations to signal the scheduler + * that a particular @a task is ready due to an event specified in the + * et field of @a fdi. + * + * This function will then queue the task to notify the application + * that the task is ready (with the respective priority). + * + * @param task the task that is ready + * @param fdi information about the related FD + */ +void +GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task, + struct GNUNET_SCHEDULER_FdInfo *fdi); + + +/** + * Handle to the scheduler's state to be used by the driver. + */ +struct GNUNET_SCHEDULER_Handle; + + +/** + * Function called by external event loop implementations to tell the + * scheduler to run some of the tasks that are ready. Must be called + * only after #GNUNET_SCHEDULER_driver_init has been called and before + * #GNUNET_SCHEDULER_driver_done is called. + * This function may return even though there are tasks left to run + * just to give other tasks a chance as well. If we return #GNUNET_YES, + * the event loop implementation should call this function again as + * soon as possible, while if we return #GNUNET_NO it must block until + * either the operating system has more work (the scheduler has no more + * work to do right now) or the timeout set by the scheduler (using the + * set_wakeup callback) is reached. + * + * @param sh scheduler handle that was returned by + * #GNUNET_SCHEDULER_driver_init + * @return #GNUNET_YES if there are more tasks that are ready, + * and thus we would like to run more (yield to avoid + * blocking other activities for too long) #GNUNET_NO + * if we are done running tasks (yield to block) + */ +int +GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh); + + +/** + * API an external event loop has to implement for + * #GNUNET_SCHEDULER_driver_init. + */ +struct GNUNET_SCHEDULER_Driver +{ + /** + * Closure to pass to the functions in this struct. + */ + void *cls; + + /** + * Add a @a task to be run if the conditions specified in the + * et field of the given @a fdi are satisfied. The et field will + * be cleared after this call and the driver is expected to set + * the type of the actual event before passing @a fdi to + * #GNUNET_SCHEDULER_task_ready. + * + * @param cls closure + * @param task task to add + * @param fdi conditions to watch for + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + * (i.e. @a fdi too high or invalid) + */ + int + (*add)(void *cls, + struct GNUNET_SCHEDULER_Task *task, + struct GNUNET_SCHEDULER_FdInfo *fdi); + + /** + * Delete a @a task from the set of tasks to be run. A task may + * comprise multiple FdInfo entries previously added with the add + * function. The driver is expected to delete them all. + * + * @param cls closure + * @param task task to delete + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + * (i.e. @a task does not match prior @e add call) + */ + int + (*del)(void *cls, + struct GNUNET_SCHEDULER_Task *task); + + /** + * Set time at which we definitively want to get a wakeup call. + * + * @param cls closure + * @param dt time when we want to wake up next + */ + void + (*set_wakeup)(void *cls, + struct GNUNET_TIME_Absolute dt); +}; + + +/** + * Signature of the main function of a task. + * + * @param cls closure + */ +typedef void +(*GNUNET_SCHEDULER_TaskCallback) (void *cls); + + +/** + * Function called by external event loop implementations to initialize + * the scheduler. An external implementation has to provide @a driver + * which contains callbacks for the scheduler (see definition of struct + * #GNUNET_SCHEDULER_Driver). The callbacks are used to instruct the + * external implementation to watch for events. If it detects any of + * those events it is expected to call #GNUNET_SCHEDULER_do_work to let + * the scheduler handle it. If an event is related to a specific task + * (e.g. the scheduler gave instructions to watch a file descriptor), + * the external implementation is expected to mark that task ready + * before by calling #GNUNET_SCHEDULER_task_ready. + * + * This function has to be called before any tasks are scheduled and + * before GNUNET_SCHEDULER_do_work is called for the first time. It + * allocates resources that have to be freed again by calling + * #GNUNET_SCHEDULER_driver_done. + * + * This function installs the same signal handlers as + * #GNUNET_SCHEDULER_run. This means SIGTERM (and other similar signals) + * will induce a call to #GNUNET_SCHEDULER_shutdown during the next + * call to #GNUNET_SCHEDULER_do_work. As a result, SIGTERM causes all + * active tasks to be scheduled with reason + * #GNUNET_SCHEDULER_REASON_SHUTDOWN. (However, tasks added afterwards + * will execute normally!). Note that any particular signal will only + * shut down one scheduler; applications should always only create a + * single scheduler. + * + * @param driver to use for the event loop + * @return handle to be passed to #GNUNET_SCHEDULER_do_work and + * #GNUNET_SCHEDULER_driver_done + */ +struct GNUNET_SCHEDULER_Handle * +GNUNET_SCHEDULER_driver_init (const struct GNUNET_SCHEDULER_Driver *driver); + + +/** + * Counter-part of #GNUNET_SCHEDULER_driver_init. Has to be called + * by external event loop implementations after the scheduler has + * shut down. This is the case if both of the following conditions + * are met: + * + * - all tasks the scheduler has added through the driver's add + * callback have been removed again through the driver's del + * callback + * - the timeout the scheduler has set through the driver's + * add_wakeup callback is FOREVER + * + * @param sh the handle returned by #GNUNET_SCHEDULER_driver_init + */ +void +GNUNET_SCHEDULER_driver_done (struct GNUNET_SCHEDULER_Handle *sh); + + +/** + * Obtain the driver for using select() as the event loop. + * + * @return NULL on error + */ +struct GNUNET_SCHEDULER_Driver * +GNUNET_SCHEDULER_driver_select (void); + + +/** + * Signature of the select function used by the scheduler. + * #GNUNET_NETWORK_socket_select matches it. + * + * @param cls closure + * @param rfds set of sockets to be checked for readability + * @param wfds set of sockets to be checked for writability + * @param efds set of sockets to be checked for exceptions + * @param timeout relative value when to return + * @return number of selected sockets, #GNUNET_SYSERR on error + */ +typedef int +(*GNUNET_SCHEDULER_select) (void *cls, + struct GNUNET_NETWORK_FDSet *rfds, + struct GNUNET_NETWORK_FDSet *wfds, + struct GNUNET_NETWORK_FDSet *efds, + struct GNUNET_TIME_Relative timeout); + + +/** + * Initialize and run scheduler. This function will return when all + * tasks have completed. On systems with signals, receiving a SIGTERM + * (and other similar signals) will cause #GNUNET_SCHEDULER_shutdown + * to be run after the active task is complete. As a result, SIGTERM + * causes all shutdown tasks to be scheduled with reason + * #GNUNET_SCHEDULER_REASON_SHUTDOWN. (However, tasks added + * afterwards will execute normally!). Note that any particular + * signal will only shut down one scheduler; applications should + * always only create a single scheduler. + * + * @param task task to run first (and immediately) + * @param task_cls closure of @a task + */ +void +GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + +/** + * Initialize and run scheduler. This function will return when all + * tasks have completed. When @ install_signals is GNUNET_YES, then + * this function behaves in the same was as GNUNET_SCHEDULER_run does. + * If @ install_signals is GNUNET_NO then no signal handlers are + * installed. + * + * @param install_signals whether to install signals (GNUNET_YES/NO) + * @param task task to run first (and immediately) + * @param task_cls closure of @a task + */ +void +GNUNET_SCHEDULER_run_with_optional_signals (int install_signals, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Request the shutdown of a scheduler. Marks all tasks + * awaiting shutdown as ready. Note that tasks + * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call + * will be delayed until the next shutdown signal. + */ +void +GNUNET_SCHEDULER_shutdown (void); + + +/** + * Get information about the current load of this scheduler. Use this + * function to determine if an elective task should be added or simply + * dropped (if the decision should be made based on the number of + * tasks ready to run). + * + * @param p priority-level to query, use KEEP to query the level + * of the current task, use COUNT to get the sum over + * all priority levels + * @return number of tasks pending right now + */ +unsigned int +GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p); + + +/** + * Obtain the reasoning why the current task was + * started. + * + * @return task context with information why the current task is run + */ +const struct GNUNET_SCHEDULER_TaskContext * +GNUNET_SCHEDULER_get_task_context (void); + + +/** + * Cancel the task with the specified identifier. + * The task must not yet have run. Only allowed to be called as long as the + * scheduler is running, that is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param task id of the task to cancel + * @return original closure of the task + */ +void * +GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task); + + +/** + * Continue the current execution with the given function. This is + * similar to the other "add" functions except that there is no delay + * and the reason code can be specified. + * + * @param task main function of the task + * @param task_cls closure for @a task + * @param reason reason for task invocation + * @param priority priority to use for the task + */ +void +GNUNET_SCHEDULER_add_with_reason_and_priority ( + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls, + enum GNUNET_SCHEDULER_Reason reason, + enum GNUNET_SCHEDULER_Priority priority); + + +/** + * Schedule a new task to be run with a specified priority. + * + * @param prio how important is the new task? + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_with_priority (enum GNUNET_SCHEDULER_Priority prio, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run as soon as possible. Note that this + * does not guarantee that this will be the next task that is being + * run, as other tasks with higher priority (or that are already ready + * to run) might get to run first. Just as with delays, clients must + * not rely on any particular order of execution between tasks + * scheduled concurrently. + * + * The task will be run with the DEFAULT priority. + * + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run on shutdown, that is when a CTRL-C + * signal is received, or when #GNUNET_SCHEDULER_shutdown() is being + * invoked. + * + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run as soon as possible with the + * (transitive) ignore-shutdown flag either explicitly set or + * explicitly enabled. This task (and all tasks created from it, + * other than by another call to this function) will either count or + * not count for the 'lifeness' of the process. This API is only + * useful in a few special cases. + * + * @param lifeness #GNUNET_YES if the task counts for lifeness, #GNUNET_NO if not. + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay. The task + * will be scheduled for execution once the delay has expired. It + * will be run with the DEFAULT priority. + * + * @param delay with which the operation should be run + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run at the specified time. The task + * will be scheduled for execution once specified time has been + * reached. It will be run with the DEFAULT priority. + * + * @param at time at which this operation should run + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_at (struct GNUNET_TIME_Absolute at, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay. The task + * will be scheduled for execution once the delay has expired. + * + * @param delay when should this operation time out? + * @param priority priority to use for the task + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_delayed_with_priority (struct GNUNET_TIME_Relative delay, + enum GNUNET_SCHEDULER_Priority + priority, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run at the specified time. The task + * will be scheduled for execution at time @a at. + * + * @param at time when the operation should run + * @param priority priority to use for the task + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, + enum GNUNET_SCHEDULER_Priority priority, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay or when the + * specified file descriptor is ready for reading. The delay can be + * used as a timeout on the socket being ready. The task will be + * scheduled for execution once either the delay has expired or the + * socket operation is ready. It will be run with the DEFAULT priority. + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param delay when should this operation time out? + * @param rfd read file-descriptor + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_read_net (struct GNUNET_TIME_Relative delay, + struct GNUNET_NETWORK_Handle *rfd, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified priority and to be + * run after the specified delay or when the specified file descriptor + * is ready for reading. The delay can be used as a timeout on the + * socket being ready. The task will be scheduled for execution once + * either the delay has expired or the socket operation is ready. It + * will be run with the DEFAULT priority. + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param delay when should this operation time out? + * @param priority priority to use for the task + * @param rfd read file-descriptor + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_read_net_with_priority (struct GNUNET_TIME_Relative delay, + enum GNUNET_SCHEDULER_Priority + priority, + struct GNUNET_NETWORK_Handle *rfd, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay or when the + * specified file descriptor is ready for writing. The delay can be + * used as a timeout on the socket being ready. The task will be + * scheduled for execution once either the delay has expired or the + * socket operation is ready. It will be run with the priority of + * the calling task. + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param delay when should this operation time out? + * @param wfd write file-descriptor + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_write_net (struct GNUNET_TIME_Relative delay, + struct GNUNET_NETWORK_Handle *wfd, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay or when the + * specified file descriptor is ready. The delay can be + * used as a timeout on the socket being ready. The task will be + * scheduled for execution once either the delay has expired or the + * socket operation is ready. + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param delay when should this operation time out? + * @param priority priority of the task + * @param fd file-descriptor + * @param on_read whether to poll the file-descriptor for readability + * @param on_write whether to poll the file-descriptor for writability + * @param task main function of the task + * @param task_cls closure of task + * @return unique task identifier for the job + * only valid until "task" is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_net_with_priority (struct GNUNET_TIME_Relative delay, + enum GNUNET_SCHEDULER_Priority priority, + struct GNUNET_NETWORK_Handle *fd, + int on_read, + int on_write, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay or when the + * specified file descriptor is ready for reading. The delay can be + * used as a timeout on the socket being ready. The task will be + * scheduled for execution once either the delay has expired or the + * socket operation is ready. It will be run with the DEFAULT priority. + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param delay when should this operation time out? + * @param rfd read file-descriptor + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_read_file (struct GNUNET_TIME_Relative delay, + const struct GNUNET_DISK_FileHandle *rfd, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay or when the + * specified file descriptor is ready for writing. The delay can be + * used as a timeout on the socket being ready. The task will be + * scheduled for execution once either the delay has expired or the + * socket operation is ready. It will be run with the DEFAULT priority. + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param delay when should this operation time out? + * @param wfd write file-descriptor + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_write_file (struct GNUNET_TIME_Relative delay, + const struct GNUNET_DISK_FileHandle *wfd, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay or when the + * specified file descriptor is ready. The delay can be + * used as a timeout on the socket being ready. The task will be + * scheduled for execution once either the delay has expired or the + * socket operation is ready. + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param delay when should this operation time out? + * @param priority priority of the task + * @param fd file-descriptor + * @param on_read whether to poll the file-descriptor for readability + * @param on_write whether to poll the file-descriptor for writability + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_file_with_priority (struct GNUNET_TIME_Relative delay, + enum GNUNET_SCHEDULER_Priority + priority, + const struct + GNUNET_DISK_FileHandle *fd, + int on_read, + int on_write, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + + +/** + * Schedule a new task to be run with a specified delay or when any of + * the specified file descriptor sets is ready. The delay can be used + * as a timeout on the socket(s) being ready. The task will be + * scheduled for execution once either the delay has expired or any of + * the socket operations is ready. This is the most general + * function of the "add" family. Note that the "prerequisite_task" + * must be satisfied in addition to any of the other conditions. In + * other words, the task will be started when + * <code> + * (prerequisite-run) + * && (delay-ready + * || any-rs-ready + * || any-ws-ready) ) + * </code> + * Only allowed to be called as long as the scheduler is running, that + * is one of the following conditions is met: + * + * - #GNUNET_SCHEDULER_run has been called and has not returned yet + * - #GNUNET_SCHEDULER_driver_init has been run and + * #GNUNET_SCHEDULER_driver_done has not been called yet + * + * @param prio how important is this task? + * @param delay how long should we wait? + * @param rs set of file descriptors we want to read (can be NULL) + * @param ws set of file descriptors we want to write (can be NULL) + * @param task main function of the task + * @param task_cls closure of @a task + * @return unique task identifier for the job + * only valid until @a task is started! + */ +struct GNUNET_SCHEDULER_Task * +GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, + struct GNUNET_TIME_Relative delay, + const struct GNUNET_NETWORK_FDSet *rs, + const struct GNUNET_NETWORK_FDSet *ws, + GNUNET_SCHEDULER_TaskCallback task, + void *task_cls); + +/** + * Sets the select function to use in the scheduler (scheduler_select). + * + * @param new_select new select function to use (NULL to reset to default) + * @param new_select_cls closure for @a new_select + */ +void +GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select, + void *new_select_cls); + + +/** + * Change the async scope for the currently executing task and (transitively) + * for all tasks scheduled by the current task after calling this function. + * Nested tasks can begin their own nested async scope. + * + * Once the current task is finished, the async scope ID is reset to + * its previous value. + * + * Must only be called from a running task. + * + * @param aid the asynchronous scope id to enter + */ +void +GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ /* end of group scheduler */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_service_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_service_lib.h @@ -0,0 +1,537 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013, 2016, 2017 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 + * @{ + * + * @addtogroup networking + * @{ + * + * @author Christian Grothoff + * + * @file + * Functions related to starting services + * + * @defgroup service Service library + * Start service processes. + * + * @see [Documentation](https://gnunet.org/developer-handbook-util-services) + * + * @{ + */ + +#ifndef GNUNET_SERVICE_LIB_H +#define GNUNET_SERVICE_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include "gnunet_util_lib.h" +#include "gnunet_configuration_lib.h" + + +/** + * Options for the service (bitmask). + */ +enum GNUNET_SERVICE_Options +{ + /** + * Use defaults. Terminates all client connections and the listen + * sockets immediately upon receiving the shutdown signal. + */ + GNUNET_SERVICE_OPTION_NONE = 0, + + /** + * Do not trigger server shutdown on signal at all; instead, allow + * for the user to terminate the server explicitly when needed + * by calling #GNUNET_SERVICE_shutdown(). + */ + GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN = 1, + + /** + * Trigger a SOFT server shutdown on signals, allowing active + * non-monitor clients to complete their transactions. + */ + GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN = 2, + + /** + * Bitmask over the shutdown options. + */ + GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK = 3, + + /** + * Instead of listening on lsocks passed by the parent, + * close them *after* opening our own listen socket(s). + */ + GNUNET_SERVICE_OPTION_CLOSE_LSOCKS = 4 +}; + + +/* **************** NEW SERVICE API ********************** */ + +/** + * Handle to a service. + */ +struct GNUNET_SERVICE_Handle; + + +/** + * Handle to a client that is connected to a service. + */ +struct GNUNET_SERVICE_Client; + + +/** + * Callback to initialize a service, called exactly once when the service is run. + * + * @param cls closure passed to #GNUNET_SERVICE_MAIN + * @param cfg configuration to use for this service + * @param sh handle to the newly create service + */ +typedef void +(*GNUNET_SERVICE_InitCallback)(void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_SERVICE_Handle *sh); + + +/** + * Callback to be called when a client connects to the service. + * + * @param cls closure for the service + * @param c the new client that connected to the service + * @param mq the message queue used to send messages to the client + * @return the client-specific (`internal') closure + */ +typedef void * +(*GNUNET_SERVICE_ConnectHandler)(void *cls, + struct GNUNET_SERVICE_Client *c, + struct GNUNET_MQ_Handle *mq); + + +/** + * Callback to be called when a client disconnected from the service + * + * @param cls closure for the service + * @param c the client that disconnected + * @param internal_cls the client-specific (`internal') closure + */ +typedef void +(*GNUNET_SERVICE_DisconnectHandler)(void *cls, + struct GNUNET_SERVICE_Client *c, + void *internal_cls); + + +/** + * Low-level function to start a service if the scheduler + * is already running. Should only be used directly in + * special cases. + * + * The function will launch the service with the name @a service_name + * using the @a service_options to configure its shutdown + * behavior. When clients connect or disconnect, the respective + * @a connect_cb or @a disconnect_cb functions will be called. For + * messages received from the clients, the respective @a handlers will + * be invoked; for the closure of the handlers we use the return value + * from the @a connect_cb invocation of the respective client. + * + * Each handler MUST call #GNUNET_SERVICE_client_continue() after each + * message to receive further messages from this client. If + * #GNUNET_SERVICE_client_continue() is not called within a short + * time, a warning will be logged. If delays are expected, services + * should call #GNUNET_SERVICE_client_disable_continue_warning() to + * disable the warning. + * + * Clients sending invalid messages (based on @a handlers) will be + * dropped. Additionally, clients can be dropped at any time using + * #GNUNET_SERVICE_client_drop(). + * + * The service must be stopped using #GNUNET_SERVICE_stop(). + * + * @param service_name name of the service to run + * @param cfg configuration to use + * @param connect_cb function to call whenever a client connects + * @param disconnect_cb function to call whenever a client disconnects + * @param cls closure argument for @a connect_cb and @a disconnect_cb + * @param handlers NULL-terminated array of message handlers for the service, + * the closure will be set to the value returned by + * the @a connect_cb for the respective connection + * @return NULL on error + */ +struct GNUNET_SERVICE_Handle * +GNUNET_SERVICE_start (const char *service_name, + const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_SERVICE_ConnectHandler connect_cb, + GNUNET_SERVICE_DisconnectHandler disconnect_cb, + void *cls, + const struct GNUNET_MQ_MessageHandler *handlers); + + +/** + * Stops a service that was started with #GNUNET_SERVICE_start(). + * + * @param srv service to stop + */ +void +GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv); + +/** + * Creates the "main" function for a GNUnet service. You + * should almost always use the #GNUNET_SERVICE_MAIN macro + * instead of calling this function directly (except + * for ARM, which should call this function directly). + * + * The function will launch the service with the name @a service_name + * using the @a service_options to configure its shutdown + * behavior. Once the service is ready, the @a init_cb will be called + * for service-specific initialization. @a init_cb will be given the + * service handler which can be used to control the service's + * availability. When clients connect or disconnect, the respective + * @a connect_cb or @a disconnect_cb functions will be called. For + * messages received from the clients, the respective @a handlers will + * be invoked; for the closure of the handlers we use the return value + * from the @a connect_cb invocation of the respective client. + * + * Each handler MUST call #GNUNET_SERVICE_client_continue() after each + * message to receive further messages from this client. If + * #GNUNET_SERVICE_client_continue() is not called within a short + * time, a warning will be logged. If delays are expected, services + * should call #GNUNET_SERVICE_client_disable_continue_warning() to + * disable the warning. + * + * Clients sending invalid messages (based on @a handlers) will be + * dropped. Additionally, clients can be dropped at any time using + * #GNUNET_SERVICE_client_drop(). + * + * @param argc number of command-line arguments in @a argv + * @param argv array of command-line arguments + * @param service_name name of the service to run + * @param options options controlling shutdown of the service + * @param service_init_cb function to call once the service is ready + * @param connect_cb function to call whenever a client connects + * @param disconnect_cb function to call whenever a client disconnects + * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb + * @param handlers NULL-terminated array of message handlers for the service, + * the closure will be set to the value returned by + * the @a connect_cb for the respective connection + * @return 0 on success, non-zero on error + */ +int +GNUNET_SERVICE_run_ (int argc, + char *const *argv, + const char *service_name, + enum GNUNET_SERVICE_Options options, + GNUNET_SERVICE_InitCallback service_init_cb, + GNUNET_SERVICE_ConnectHandler connect_cb, + GNUNET_SERVICE_DisconnectHandler disconnect_cb, + void *cls, + const struct GNUNET_MQ_MessageHandler *handlers); + + +/** + * Registers the GNUnet service to be scheduled as part of a monilithic + * libgnunet. + * You should almost always use the #GNUNET_SERVICE_MAIN macro + * instead of calling this function directly. + * + * The function will launch the service with the name @a service_name + * using the @a service_options to configure its shutdown + * behavior. Once the service is ready, the @a init_cb will be called + * for service-specific initialization. @a init_cb will be given the + * service handler which can be used to control the service's + * availability. When clients connect or disconnect, the respective + * @a connect_cb or @a disconnect_cb functions will be called. For + * messages received from the clients, the respective @a handlers will + * be invoked; for the closure of the handlers we use the return value + * from the @a connect_cb invocation of the respective client. + * + * Each handler MUST call #GNUNET_SERVICE_client_continue() after each + * message to receive further messages from this client. If + * #GNUNET_SERVICE_client_continue() is not called within a short + * time, a warning will be logged. If delays are expected, services + * should call #GNUNET_SERVICE_client_disable_continue_warning() to + * disable the warning. + * + * Clients sending invalid messages (based on @a handlers) will be + * dropped. Additionally, clients can be dropped at any time using + * #GNUNET_SERVICE_client_drop(). + * + * @param service_name name of the service to run + * @param options options controlling shutdown of the service + * @param service_init_cb function to call once the service is ready + * @param connect_cb function to call whenever a client connects + * @param disconnect_cb function to call whenever a client disconnects + * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb + * @param handlers NULL-terminated array of message handlers for the service, + * the closure will be set to the value returned by + * the @a connect_cb for the respective connection + * @return 0 on success, non-zero on error + */ +int +GNUNET_SERVICE_register_ ( + const char *service_name, + enum GNUNET_SERVICE_Options options, + GNUNET_SERVICE_InitCallback service_init_cb, + GNUNET_SERVICE_ConnectHandler connect_cb, + GNUNET_SERVICE_DisconnectHandler disconnect_cb, + void *cls, + const struct GNUNET_MQ_MessageHandler *handlers); + + +/** + * Creates the "main" function for a GNUnet service. You + * MUST use this macro to define GNUnet services (except + * for ARM, which MUST NOT use the macro). The reason is + * the GNUnet-as-a-library project, where we will not define + * a main function anywhere but in ARM. + * + * The macro will launch the service with the name @a service_name + * using the @a service_options to configure its shutdown + * behavior. Once the service is ready, the @a init_cb will be called + * for service-specific initialization. @a init_cb will be given the + * service handler which can be used to control the service's + * availability. When clients connect or disconnect, the respective + * @a connect_cb or @a disconnect_cb functions will be called. For + * messages received from the clients, the respective @a handlers will + * be invoked; for the closure of the handlers we use the return value + * from the @a connect_cb invocation of the respective client. + * + * Each handler MUST call #GNUNET_SERVICE_client_continue() after each + * message to receive further messages from this client. If + * #GNUNET_SERVICE_client_continue() is not called within a short + * time, a warning will be logged. If delays are expected, services + * should call #GNUNET_SERVICE_client_disable_continue_warning() to + * disable the warning. + * + * Clients sending invalid messages (based on @a handlers) will be + * dropped. Additionally, clients can be dropped at any time using + * #GNUNET_SERVICE_client_drop(). + * + * @param service_name name of the service to run + * @param service_options options controlling shutdown of the service + * @param init_cb function to call once the service is ready + * @param connect_cb function to call whenever a client connects + * @param disconnect_cb function to call whenever a client disconnects + * @param cls closure argument for @a service_init_cb, @a connect_cb and @a disconnect_cb + * @param ... array of message handlers for the service, terminated + * by #GNUNET_MQ_handler_end(); + * the closure will be set to the value returned by + * the @a connect_cb for the respective connection + * @return 0 on success, non-zero on error + * + * Sample invocation: + * <code> + * GNUNET_SERVICE_MAIN + * ("resolver", + * GNUNET_SERVICE_OPTION_NONE, + * &init_cb, + * &connect_cb, + * &disconnect_cb, + * closure_for_cb, + * GNUNET_MQ_hd_var_size (get, + * GNUNET_MESSAGE_TYPE_RESOLVER_REQUEST, + * struct GNUNET_RESOLVER_GetMessage, + * NULL), + * GNUNET_MQ_handler_end ()); + * </code> + */ +#ifndef HAVE_GNUNET_MONOLITH +#define GNUNET_SERVICE_MAIN(service_name, service_options, init_cb, connect_cb, \ + disconnect_cb, cls, ...) \ + int \ + main (int argc, \ + char *const *argv) \ + { \ + struct GNUNET_MQ_MessageHandler mh[] = { \ + __VA_ARGS__ \ + }; \ + return GNUNET_SERVICE_run_ (argc, \ + argv, \ + service_name, \ + service_options, \ + init_cb, \ + connect_cb, \ + disconnect_cb, \ + cls, \ + mh); \ + } +#else +#define GNUNET_SERVICE_MAIN(service_name, service_options, init_cb, connect_cb, \ + disconnect_cb, cls, ...) \ + static int __attribute__ ((constructor)) \ + init (void) \ + { \ + struct GNUNET_MQ_MessageHandler mh[] = { \ + __VA_ARGS__ \ + }; \ + return GNUNET_SERVICE_register_ (service_name, \ + service_options, \ + init_cb, \ + connect_cb, \ + disconnect_cb, \ + cls, \ + mh); \ + } +#endif + +/** + * Run the mainloop in a monolithic libgnunet. + * Must be called such that services are actually launched. + */ +void +GNUNET_SERVICE_main (int argc, + char *const *argv, + struct GNUNET_CONFIGURATION_Handle *cfg); + +/** + * Suspend accepting connections from the listen socket temporarily. + * Resume activity using #GNUNET_SERVICE_resume. + * + * @param sh service to stop accepting connections. + */ +void +GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh); + + +/** + * Resume accepting connections from the listen socket. + * + * @param sh service to resume accepting connections. + */ +void +GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh); + + +/** + * Continue receiving further messages from the given client. + * Must be called after each message received. + * + * @param c the client to continue receiving from + */ +void +GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c); + + +/** + * Obtain the message queue of @a c. Convenience function. + * + * @param c the client to continue receiving from + * @return the message queue of @a c + */ +struct GNUNET_MQ_Handle * +GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c); + + +/** + * Disable the warning the server issues if a message is not + * acknowledged in a timely fashion. Use this call if a client is + * intentionally delayed for a while. Only applies to the current + * message. + * + * @param c client for which to disable the warning + */ +void +GNUNET_SERVICE_client_disable_continue_warning (struct + GNUNET_SERVICE_Client *c); + + +/** + * Ask the server to disconnect from the given client. This is the + * same as returning #GNUNET_SYSERR within the check procedure when + * handling a message, except that it allows dropping of a client even + * when not handling a message from that client. The `disconnect_cb` + * will be called on @a c even if the application closes the connection + * using this function. + * + * This function should be called (outside of util's internal logic) + * if (and usually only if) the client has violated the + * protocol. Otherwise, we should leave it to the client to disconnect + * from the service. + * + * @param c client to disconnect now + */ +void +GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c); + + +/** + * Explicitly stops the service. + * + * @param sh server to shutdown + */ +void +GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh); + + +/** + * Set the 'monitor' flag on this client. Clients which have been + * marked as 'monitors' won't prevent the server from shutting down + * once #GNUNET_SERVICE_stop_listening() has been invoked. The idea is + * that for "normal" clients we likely want to allow them to process + * their requests; however, monitor-clients are likely to 'never' + * disconnect during shutdown and thus will not be considered when + * determining if the server should continue to exist after + * shutdown has been triggered. + * + * @param c client to mark as a monitor + */ +void +GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c); + + +/** + * Set the persist option on this client. Indicates that the + * underlying socket or fd should never really be closed. Used for + * indicating process death. + * + * @param c client to persist the socket (never to be closed) + */ +void +GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_SERVICE_LIB_H */ +#endif + +/** @} */ /* end of group service */ + +/** @} */ /* end of group addition to networking*/ + +/** @} */ /* end of group addition to libgnunetutil */ + +/* end of gnunet_service_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_signal_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_signal_lib.h @@ -0,0 +1,118 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 + * + * @file + * Functions related to signals + * + * @defgroup signal Signal library + * Manage signal handlers. + * @{ + */ + +#ifndef GNUNET_SIGNAL_LIB_H +#define GNUNET_SIGNAL_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +/** + * Context created when a signal handler is installed; + * can be used to restore it to the previous state later. + */ +struct GNUNET_SIGNAL_Context; + + +/** + * A signal handler. Since different OSes have different signatures + * for their handlers, the API only gives the most restrictive + * signature -- no arguments, no return value. Note that this will + * work even if the OS expects a function with arguments. However, + * the implementation must guarantee that this handler is not called + * for signals other than the one that it has been registered for. + */ +typedef void +(*GNUNET_SIGNAL_Handler) (void); + + +/** + * Install a signal handler that will be run if the + * given signal is received. + * + * @param signal the number of the signal + * @param handler the function to call + * @return context that can be used to restore, NULL on error + */ +struct GNUNET_SIGNAL_Context * +GNUNET_SIGNAL_handler_install (int signal, + GNUNET_SIGNAL_Handler handler); + + +/** + * Uninstall a previously installed signal handler. + * + * @param ctx context that was returned when the + * signal handler was installed + */ +void +GNUNET_SIGNAL_handler_uninstall (struct GNUNET_SIGNAL_Context *ctx); + + +/** + * Raise the given signal by calling the installed signal handlers. This will + * not use the @em raise() system call but only calls the handlers registered + * through GNUNET_SIGNAL_handler_install(). + * + * @param sig the signal to raise + */ +void +GNUNET_SIGNAL_raise (const int sig); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_SIGNAL_LIB_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_signal_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_sq_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_sq_lib.h @@ -0,0 +1,571 @@ +/* + This file is part of GNUnet + Copyright (C) 2017 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 include/gnunet_sq_lib.h + * @brief helper functions for Sqlite3 DB interactions + * @author Christian Grothoff + */ +#ifndef GNUNET_SQ_LIB_H +#define GNUNET_SQ_LIB_H + + +#include <sqlite3.h> +#include "gnunet_util_lib.h" + + +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument + * @param data_len number of bytes in @a data (if applicable) + * @param stmt sqlite statement to bind parameters for + * @param off offset of the argument to bind in @a stmt, numbered from 1, + * so immediately suitable for passing to `sqlite3_bind`-functions. + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_SQ_QueryConverter)(void *cls, + const void *data, + size_t data_len, + sqlite3_stmt *stmt, + unsigned int off); + + +/** + * @brief Description of a DB query parameter. + */ +struct GNUNET_SQ_QueryParam +{ + /** + * Function for how to handle this type of entry. + */ + GNUNET_SQ_QueryConverter conv; + + /** + * Closure for @e conv. + */ + void *conv_cls; + + /** + * Data or NULL. + */ + const void *data; + + /** + * Size of @e data + */ + size_t size; + + /** + * Number of parameters eaten by this operation. + */ + unsigned int num_params; +}; + + +/** + * End of query parameter specification. + */ +#define GNUNET_SQ_query_param_end { NULL, NULL, NULL, 0, 0 } + + +/** + * Generate query parameter for a buffer @a ptr of + * @a ptr_size bytes. + * + * @param ptr pointer to the query parameter to pass + * @param ptr_size number of bytes in @a ptr + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_fixed_size (const void *ptr, + size_t ptr_size); + + +/** + * Generate query parameter for a string. + * + * @param ptr pointer to the string query parameter to pass + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_string (const char *ptr); + + +/** + * Generate fixed-size query parameter with size determined + * by variable type. + * + * @param x pointer to the query parameter to pass. + */ +#define GNUNET_SQ_query_param_auto_from_type( \ + x) GNUNET_SQ_query_param_fixed_size ((x), sizeof(*(x))) + + +/** + * Generate query parameter for an RSA public key. The + * database must contain a BLOB type in the respective position. + * + * @param x the query parameter to pass. + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_rsa_public_key (const struct + GNUNET_CRYPTO_RsaPublicKey *x); + + +/** + * Generate query parameter for an RSA signature. The + * database must contain a BLOB type in the respective position. + * + * @param x the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_rsa_signature (const struct + GNUNET_CRYPTO_RsaSignature *x); + + +/** + * Generate query parameter for an absolute time value. + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); + + +/** + * Generate query parameter for an absolute time value. + * The database must store a 64-bit integer. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_absolute_time_nbo ( + const struct GNUNET_TIME_AbsoluteNBO *x); + + +/** + * Generate query parameter for an uint16_t in host byte order. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_uint16 (const uint16_t *x); + + +/** + * Generate query parameter for an uint32_t in host byte order. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_uint32 (const uint32_t *x); + + +/** + * Generate query parameter for an uint16_t in host byte order. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_SQ_QueryParam +GNUNET_SQ_query_param_uint64 (const uint64_t *x); + + +/** + * Execute binding operations for a prepared statement. + * + * @param db_conn database connection + * @param params parameters to the statement + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_SQ_bind (sqlite3_stmt *stmt, + const struct GNUNET_SQ_QueryParam *params); + + +/** + * Reset @a stmt and log error. + * + * @param dbh database handle + * @param stmt statement to reset + */ +void +GNUNET_SQ_reset (sqlite3 *dbh, + sqlite3_stmt *stmt); + + +/** + * Extract data from a Postgres database @a result at row @a row. + * + * @param cls closure + * @param result where to extract data from + * @param column column to extract data from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +typedef enum GNUNET_GenericReturnValue +(*GNUNET_SQ_ResultConverter)(void *cls, + sqlite3_stmt *result, + unsigned int column, + size_t *dst_size, + void *dst); + + +/** + * @brief Description of a DB result cell. + */ +struct GNUNET_SQ_ResultSpec; + + +/** + * Function called to clean up memory allocated + * by a #GNUNET_SQ_ResultConverter. + * + * @param cls closure + */ +typedef void +(*GNUNET_SQ_ResultCleanup)(void *cls); + + +/** + * @brief Description of a DB result cell. + */ +struct GNUNET_SQ_ResultSpec +{ + /** + * What is the format of the result? + */ + GNUNET_SQ_ResultConverter conv; + + /** + * Function to clean up result data, NULL if cleanup is + * not necessary. + */ + GNUNET_SQ_ResultCleanup cleaner; + + /** + * Closure for @e conv and @e cleaner. + */ + void *cls; + + /** + * Destination for the data. + */ + void *dst; + + /** + * Allowed size for the data, 0 for variable-size + * (in this case, the type of @e dst is a `void **` + * and we need to allocate a buffer of the right size). + */ + size_t dst_size; + + /** + * Where to store actual size of the result. If left at + * NULL, will be made to point to @e dst_size before + * @a conv is called. + */ + size_t *result_size; + + /** + * Number of parameters (columns) eaten by this operation. + */ + unsigned int num_params; +}; + + +/** + * End of result parameter specification. + * + * @return array last entry for the result specification to use + */ +#define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL, 0 } + + +/** + * Variable-size result expected. + * + * @param[out] dst where to store the result, allocated + * @param[out] sptr where to store the size of @a dst + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_variable_size (void **dst, + size_t *sptr); + + +/** + * Fixed-size result expected. + * + * @param[out] dst where to store the result + * @param dst_size number of bytes in @a dst + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_fixed_size (void *dst, + size_t dst_size); + + +/** + * We expect a fixed-size result, with size determined by the type of `* dst` + * + * @param dst point to where to store the result, type fits expected result size + * @return array entry for the result specification to use + */ +#define GNUNET_SQ_result_spec_auto_from_type( \ + dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof(*(dst))) + + +/** + * Variable-size result expected. + * + * @param[out] dst where to store the result, allocated + * @param[out] sptr where to store the size of @a dst + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_variable_size (void **dst, + size_t *sptr); + + +/** + * 0-terminated string expected. + * + * @param[out] dst where to store the result, allocated + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_string (char **dst); + + +/** + * RSA public key expected. + * + * @param[out] rsa where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa); + + +/** + * RSA signature expected. + * + * @param[out] sig where to store the result; + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig); + + +/** + * Absolute time expected. + * + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at); + + +/** + * Absolute time expected. + * + * @param[out] at where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at); + + +/** + * uint16_t expected. + * + * @param[out] u16 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_uint16 (uint16_t *u16); + + +/** + * uint32_t expected. + * + * @param[out] u32 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_uint32 (uint32_t *u32); + + +/** + * uint64_t expected. + * + * @param[out] u64 where to store the result + * @return array entry for the result specification to use + */ +struct GNUNET_SQ_ResultSpec +GNUNET_SQ_result_spec_uint64 (uint64_t *u64); + + +/** + * Extract results from a query result according to the given specification. + * + * @param result result to process + * @param[in,out] rs result specification to extract for + * @return + * #GNUNET_OK if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field) + */ +enum GNUNET_GenericReturnValue +GNUNET_SQ_extract_result (sqlite3_stmt *result, + struct GNUNET_SQ_ResultSpec *rs); + + +/** + * Free all memory that was allocated in @a rs during + * #GNUNET_SQ_extract_result(). + * + * @param rs reult specification to clean up + */ +void +GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs); + + +/* ******************** sq_prepare.c functions ************** */ + + +/** + * Information needed to run a list of SQL statements using + * #GNUNET_SQ_exec_statements(). + */ +struct GNUNET_SQ_PrepareStatement +{ + /** + * Actual SQL statement. + */ + const char *sql; + + /** + * Where to store handle? + */ + sqlite3_stmt **pstmt; +}; + + +/** + * Terminator for executable statement list. + */ +#define GNUNET_SQ_PREPARE_END { NULL, NULL } + + +/** + * Create a `struct GNUNET_SQ_PrepareStatement` + * + * @param sql actual SQL statement + * @param pstmt where to store the handle + * @return initialized struct + */ +struct GNUNET_SQ_PrepareStatement +GNUNET_SQ_make_prepare (const char *sql, + sqlite3_stmt **pstmt); + + +/** + * Prepare all statements given in the (NULL,NULL)-terminated + * array at @a ps + * + * @param dbh database handle + * @param ps array of statements to prepare + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_SQ_prepare (sqlite3 *dbh, + const struct GNUNET_SQ_PrepareStatement *ps); + + +/* ******************** sq_exec.c functions ************** */ + + +/** + * Information needed to run a list of SQL statements using + * #GNUNET_SQ_exec_statements(). + */ +struct GNUNET_SQ_ExecuteStatement +{ + /** + * Actual SQL statement. + */ + const char *sql; + + /** + * Should we ignore errors? + */ + bool ignore_errors; +}; + + +/** + * Terminator for executable statement list. + */ +#define GNUNET_SQ_EXECUTE_STATEMENT_END { NULL, GNUNET_SYSERR } + + +/** + * Create a `struct GNUNET_SQ_ExecuteStatement` where errors are fatal. + * + * @param sql actual SQL statement + * @return initialized struct + */ +struct GNUNET_SQ_ExecuteStatement +GNUNET_SQ_make_execute (const char *sql); + + +/** + * Create a `struct GNUNET_SQ_ExecuteStatement` where errors should + * be tolerated. + * + * @param sql actual SQL statement + * @return initialized struct + */ +struct GNUNET_SQ_ExecuteStatement +GNUNET_SQ_make_try_execute (const char *sql); + + +/** + * Request execution of an array of statements @a es from Postgres. + * + * @param dbh database to execute the statements over + * @param es #GNUNET_PQ_PREPARED_STATEMENT_END-terminated array of prepared + * statements. + * @return #GNUNET_OK on success (modulo statements where errors can be ignored) + * #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_SQ_exec_statements (sqlite3 *dbh, + const struct GNUNET_SQ_ExecuteStatement *es); + + +#endif /* GNUNET_SQ_LIB_H_ */ + +/* end of include/gnunet_sq_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_statistics_service.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_statistics_service.h @@ -0,0 +1,236 @@ +/* + This file is part of GNUnet + Copyright (C) 2009-2013, 2016 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 + * API to create, modify and access statistics. + * + * @defgroup statistics Statistics service + * Track statistics or provide access to statistics. + * + * Create, modify and access statistics about the operation of GNUnet. + * + * All statistical values must be of type `unsigned long long`. + * + * @see [Documentation](https://gnunet.org/gnunet-statistics-subsystem) + * + * @{ + */ + +#ifndef GNUNET_STATISTICS_SERVICE_H +#define GNUNET_STATISTICS_SERVICE_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_util_lib.h" + +/** + * Version of the statistics API. + */ +#define GNUNET_STATISTICS_VERSION 0x00000000 + +/** + * Opaque handle for the statistics service. + */ +struct GNUNET_STATISTICS_Handle; + +/** + * Callback function to process statistic values. + * + * @param cls closure + * @param subsystem name of subsystem that created the statistic + * @param name the name of the datum + * @param value the current value + * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not + * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration + */ +typedef int +(*GNUNET_STATISTICS_Iterator) (void *cls, + const char *subsystem, + const char *name, + uint64_t value, + int is_persistent); + + +/** + * Get handle for the statistics service. + * + * @param subsystem name of subsystem using the service + * @param cfg services configuration in use + * @return handle to use + */ +struct GNUNET_STATISTICS_Handle * +GNUNET_STATISTICS_create (const char *subsystem, + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Destroy a handle (free all state associated with it). + * + * @param h statistics handle to destroy + * @param sync_first set to #GNUNET_YES if pending SET requests should + * be completed + */ +void +GNUNET_STATISTICS_destroy (struct GNUNET_STATISTICS_Handle *h, + int sync_first); + + +/** + * Watch statistics from the peer (be notified whenever they change). + * + * @param handle identification of the statistics service + * @param subsystem limit to the specified subsystem, never NULL + * @param name name of the statistic value, never NULL + * @param proc function to call on each value + * @param proc_cls closure for @a proc + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +int +GNUNET_STATISTICS_watch (struct GNUNET_STATISTICS_Handle *handle, + const char *subsystem, + const char *name, + GNUNET_STATISTICS_Iterator proc, + void *proc_cls); + + +/** + * Stop watching statistics from the peer. + * + * @param handle identification of the statistics service + * @param subsystem limit to the specified subsystem, never NULL + * @param name name of the statistic value, never NULL + * @param proc function to call on each value + * @param proc_cls closure for @a proc + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (no such watch) + */ +int +GNUNET_STATISTICS_watch_cancel (struct GNUNET_STATISTICS_Handle *handle, + const char *subsystem, + const char *name, + GNUNET_STATISTICS_Iterator proc, + void *proc_cls); + + +/** + * Continuation called by #GNUNET_STATISTICS_get() functions. + * + * @param cls closure + * @param success #GNUNET_OK if statistics were + * successfully obtained, #GNUNET_SYSERR if not. + */ +typedef void +(*GNUNET_STATISTICS_Callback) (void *cls, + int success); + + +/** + * Handle that can be used to cancel a statistics 'get' operation. + */ +struct GNUNET_STATISTICS_GetHandle; + + +/** + * Get statistic from the peer. + * + * @param handle identification of the statistics service + * @param subsystem limit to the specified subsystem, NULL for all subsystems + * @param name name of the statistic value, NULL for all values + * @param cont continuation to call when done (can be NULL) + * This callback CANNOT destroy the statistics handle in the same call. + * @param proc function to call on each value + * @param cls closure for @a proc and @a cont + * @return NULL on error + */ +struct GNUNET_STATISTICS_GetHandle * +GNUNET_STATISTICS_get (struct GNUNET_STATISTICS_Handle *handle, + const char *subsystem, + const char *name, + GNUNET_STATISTICS_Callback cont, + GNUNET_STATISTICS_Iterator proc, + void *cls); + + +/** + * Cancel a #GNUNET_STATISTICS_get request. Must be called before the 'cont' + * function is called. + * + * @param gh handle of the request to cancel + */ +void +GNUNET_STATISTICS_get_cancel (struct GNUNET_STATISTICS_GetHandle *gh); + + +/** + * Set statistic value for the peer. Will always use our + * subsystem (the argument used when @a handle was created). + * + * @param handle identification of the statistics service + * @param name name of the statistic value + * @param value new value to set + * @param make_persistent should the value be kept across restarts? + */ +void +GNUNET_STATISTICS_set (struct GNUNET_STATISTICS_Handle *handle, + const char *name, + uint64_t value, + int make_persistent); + + +/** + * Set statistic value for the peer. Will always use our + * subsystem (the argument used when @a handle was created). + * + * @param handle identification of the statistics service + * @param name name of the statistic value + * @param delta change in value (added to existing value) + * @param make_persistent should the value be kept across restarts? + */ +void +GNUNET_STATISTICS_update (struct GNUNET_STATISTICS_Handle *handle, + const char *name, + int64_t delta, + int make_persistent); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/** @} */ /* end of group statistics */ + +/** @} */ /* end of group addition */ + +#endif diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_strings_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_strings_lib.h @@ -0,0 +1,804 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-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 + */ + +#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 + * + * @file + * Strings and string handling functions + * + * @defgroup strings Strings library + * Strings and string handling functions, including malloc and string tokenizing. + * @{ + */ + +#if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) +#error "Only <gnunet_util_lib.h> can be included directly." +#endif + +#ifndef GNUNET_STRINGS_LIB_H +#define GNUNET_STRINGS_LIB_H + +/* 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 <sys/socket.h> +#include <netinet/in.h> +#include <netinet/ip.h> + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include "gnunet_time_lib.h" + + +/** + * Convert a given fancy human-readable size to bytes. + * + * @param fancy_size human readable string (e.g. 1 MB) + * @param size set to the size in bytes + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, + unsigned long long *size); + + +/** + * Convert a given fancy human-readable time to our internal + * representation. + * + * @param fancy_time human readable string (e.g. 1 minute) + * @param rtime set to the relative time + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time, + struct GNUNET_TIME_Relative *rtime); + + +/** + * @ingroup time + * Convert a given fancy human-readable time to our internal + * representation. The human-readable time is expected to be + * in local time, whereas the returned value will be in UTC. + * + * @param fancy_time human readable string (e.g. %Y-%m-%d %H:%M:%S) + * @param atime set to the absolute time + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time, + struct GNUNET_TIME_Absolute *atime); + + +/** + * @ingroup time + * Convert a given fancy human-readable time to our internal + * representation. The human-readable time is expected to be + * in local time, whereas the returned value will be in UTC. + * + * @param fancy_time human readable string (e.g. %Y-%m-%d %H:%M:%S) + * @param atime set to the absolute time + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_fancy_time_to_timestamp (const char *fancy_time, + struct GNUNET_TIME_Timestamp *atime); + + +/** + * Convert a given filesize into a fancy human-readable format. + * + * @param size number of bytes + * @return fancy representation of the size (possibly rounded) for humans + */ +char * +GNUNET_STRINGS_byte_size_fancy (unsigned long long size); + + +/** + * Convert the len characters long character sequence + * given in input that is in the given input charset + * to a string in given output charset. + * + * @param input input string + * @param len number of bytes in @a input + * @param input_charset character set used for @a input + * @param output_charset desired character set for the return value + * @return the converted string (0-terminated), + * if conversion fails, a copy of the original + * string is returned. + */ +char * +GNUNET_STRINGS_conv (const char *input, + size_t len, + const char *input_charset, + const char *output_charset); + + +/** + * Convert the len characters long character sequence + * given in input that is in the given charset + * to UTF-8. + * + * @param input the input string (not necessarily 0-terminated) + * @param len the number of bytes in the @a input + * @param charset character set to convert from + * @return the converted string (0-terminated) + */ +char * +GNUNET_STRINGS_to_utf8 (const char *input, + size_t len, + const char *charset); + + +/** + * Normalize the utf-8 input string to NFC. + * + * @param input input string + * @return result (freshly allocated) or NULL on error. + */ +char* +GNUNET_STRINGS_utf8_normalize (const char *input); + + +/** + * Convert the len bytes-long UTF-8 string + * given in input to the given charset. + * + * @param input the input string (not necessarily 0-terminated) + * @param len the number of bytes in the @a input + * @param charset character set to convert to + * @return the converted string (0-terminated), + * if conversion fails, a copy of the original + * string is returned. + */ +char * +GNUNET_STRINGS_from_utf8 (const char *input, + size_t len, + const char *charset); + + +/** + * Convert the utf-8 input string to lower case. + * Output needs to be allocated appropriately. + * + * @param input input string + * @param output output buffer + * @return GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_utf8_tolower (const char *input, + char *output); + + +/** + * Convert the utf-8 input string to upper case. + * Output needs to be allocated appropriately. + * + * @param input input string + * @param output output buffer + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_utf8_toupper (const char *input, + char *output); + + +/** + * Complete filename (a la shell) from abbrevition. + * + * @param fil the name of the file, may contain ~/ or + * be relative to the current directory + * @return the full file name, + * NULL is returned on error + */ +char * +GNUNET_STRINGS_filename_expand (const char *fil); + + +/** + * Fill a buffer of the given size with count 0-terminated strings + * (given as varargs). If "buffer" is NULL, only compute the amount + * of space required (sum of "strlen(arg)+1"). + * + * Unlike using "snprintf" with "%s", this function will add + * 0-terminators after each string. The + * "GNUNET_string_buffer_tokenize" function can be used to parse the + * buffer back into individual strings. + * + * @param buffer the buffer to fill with strings, can + * be NULL in which case only the necessary + * amount of space will be calculated + * @param size number of bytes available in buffer + * @param count number of strings that follow + * @param ... count 0-terminated strings to copy to buffer + * @return number of bytes written to the buffer + * (or number of bytes that would have been written) + */ +size_t +GNUNET_STRINGS_buffer_fill (char *buffer, + size_t size, + unsigned int count, + ...); + + +/** + * Given a buffer of a given size, find "count" 0-terminated strings + * in the buffer and assign the count (varargs) of type "const char**" + * to the locations of the respective strings in the buffer. + * + * @param buffer the buffer to parse + * @param size size of the @a buffer + * @param count number of strings to locate + * @param ... pointers to where to store the strings + * @return offset of the character after the last 0-termination + * in the buffer, or 0 on error. + */ +unsigned int +GNUNET_STRINGS_buffer_tokenize (const char *buffer, + size_t size, + unsigned int count, ...); + + +/** + * @ingroup time + * Like `asctime`, except for GNUnet time. Converts a GNUnet internal + * absolute time (which is in UTC) to a string in local time. + * Note that the returned value will be overwritten if this function + * is called again. + * + * @param t the absolute time to convert + * @return timestamp in human-readable form in local time + */ +const char * +GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t); + + +/** + * @ingroup time + * Give relative time in human-readable fancy format. + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param delta time in milli seconds + * @param do_round are we allowed to round a bit? + * @return string in human-readable form + */ +const char * +GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta, + int do_round); + + +/** + * "man basename" + * Returns a pointer to a part of filename (allocates nothing)! + * + * @param filename filename to extract basename from + * @return short (base) name of the file (that is, everything following the + * last directory separator in filename. If filename ends with a + * directory separator, the result will be a zero-length string. + * If filename has no directory separators, the result is filename + * itself. + */ +const char * +GNUNET_STRINGS_get_short_name (const char *filename); + + +/** + * Convert binary data to ASCII encoding using CrockfordBase32. + * Does not append 0-terminator, but returns a pointer to the place where + * it should be placed, if needed. + * + * @param data data to encode + * @param size size of data (in bytes) + * @param out buffer to fill + * @param out_size size of the buffer. Must be large enough to hold + * ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 + * @return pointer to the next byte in 'out' or NULL on error. + */ +char * +GNUNET_STRINGS_data_to_string (const void *data, + size_t size, + char *out, + size_t out_size); + + +/** + * Return the base32crockford encoding of the given buffer. + * + * The returned string will be freshly allocated, and must be free'd + * with #GNUNET_free(). + * + * @param buf buffer with data + * @param size size of the buffer @a buf + * @return freshly allocated, null-terminated string + */ +char * +GNUNET_STRINGS_data_to_string_alloc (const void *buf, + size_t size); + + +/** + * Convert CrockfordBase32 encoding back to data. + * @a out_size must match exactly the size of the data before it was encoded. + * + * @param enc the encoding + * @param enclen number of characters in @a enc (without 0-terminator, which can be missing) + * @param out location where to store the decoded data + * @param out_size size of the output buffer @a out + * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_string_to_data (const char *enc, + size_t enclen, + void *out, + size_t out_size); + + +/** + * Convert CrockfordBase32 encoding back to data. + * @a out_size will be determined from @a enc and + * @a out will be allocated to be large enough. + * + * @param enc the encoding + * @param enclen number of characters in @a enc (without 0-terminator, which can be missing) + * @param[out] out location where to allocate and store the decoded data + * @param[out] out_size set to the size of the output buffer @a out + * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_string_to_data_alloc (const char *enc, + size_t enclen, + void **out, + size_t *out_size); + + +/** + * Encode into Base64. + * + * @param data the data to encode + * @param len the length of the input + * @param output where to write the output (*output should be NULL, + * is allocated) + * @return the size of the output + */ +size_t +GNUNET_STRINGS_base64_encode (const void *in, + size_t len, + char **output); + + +/** + * url/percent encode (RFC3986). + * + * FIXME: awkward API, @a len is not actually used + * @a out is 0-terminated, should probably be changed + * to only input @a data and directly return @out or NULL. + * + * @param data the data to decode + * @param len the length of the input + * @param out where to write the output (*out should be NULL, + * is allocated) + * @return the size of the output + */ +size_t +GNUNET_STRINGS_urlencode (size_t len, + const char data[static len], + char **out); + + +/** + * Encode into Base64url. RFC7515 + * + * @param in the data to encode + * @param len the length of the input + * @param output where to write the output (*output should be NULL, + * is allocated) + * @return the size of the output + */ +size_t +GNUNET_STRINGS_base64url_encode (const void *in, + size_t len, + char **output); + + +/** + * Decode from Base64. + * + * @param data the data to encode + * @param len the length of the input + * @param[out] output where to write the output (*output should be NULL, + * is allocated) + * @return the size of the output + */ +size_t +GNUNET_STRINGS_base64_decode (const char *data, + size_t len, + void **output); + + +/** + * Decode from Base64url. RFC7515 + * + * @param data the data to decode + * @param len the length of the input + * @param out where to write the output (*out should be NULL, + * is allocated) + * @return the size of the output + */ +size_t +GNUNET_STRINGS_base64url_decode (const char *data, + size_t len, + void **out); + +/** + * url/percent encode (RFC3986). + * + * @param data the data to encode + * @param len the length of the input + * @param[out] out where to write the output (*output should be NULL, + * is allocated) + * @return the size of the output + */ +size_t +GNUNET_STRINGS_urldecode (const char *data, + size_t len, + char **out); + + +/** + * Parse a path that might be an URI. + * + * @param path path to parse. Must be NULL-terminated. + * @param[out] scheme_part pointer to a string that + * represents the URI scheme will be stored. Can be NULL. The string is + * allocated by the function, and should be freed by GNUNET_free() when + * it is no longer needed. + * @param path_part a pointer to 'const char *' where a pointer to the path + * part of the URI will be stored. Can be NULL. Points to the same block + * of memory as @a path, and thus must not be freed. Might point to '\0', + * if path part is zero-length. + * @return #GNUNET_YES if it's an URI, #GNUNET_NO otherwise. If 'path' is not + * an URI, '* scheme_part' and '*path_part' will remain unchanged + * (if they weren't NULL). + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_parse_uri (const char *path, + char **scheme_part, + const char **path_part); + + +/** + * Check whether filename is absolute or not, and if it's an URI + * + * @param filename filename to check + * @param can_be_uri #GNUNET_YES to check for being URI, #GNUNET_NO - to + * assume it's not URI + * @param r_is_uri a pointer to an int that is set to #GNUNET_YES if 'filename' + * is URI and to GNUNET_NO otherwise. Can be NULL. If 'can_be_uri' is + * not #GNUNET_YES, *r_is_uri is set to #GNUNET_NO. + * @param r_uri_scheme a pointer to a char * that is set to a pointer to URI scheme. + * The string is allocated by the function, and should be freed with + * GNUNET_free (). Can be NULL. + * @return #GNUNET_YES if 'filename' is absolute, #GNUNET_NO otherwise. + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_path_is_absolute (const char *filename, + int can_be_uri, + int *r_is_uri, + char **r_uri_scheme); + + +/** + * Flags for what we should check a file for. + */ +enum GNUNET_STRINGS_FilenameCheck +{ + /** + * Check that it exists. + */ + GNUNET_STRINGS_CHECK_EXISTS = 0x00000001, + + /** + * Check that it is a directory. + */ + GNUNET_STRINGS_CHECK_IS_DIRECTORY = 0x00000002, + + /** + * Check that it is a link. + */ + GNUNET_STRINGS_CHECK_IS_LINK = 0x00000004, + + /** + * Check that the path is an absolute path. + */ + GNUNET_STRINGS_CHECK_IS_ABSOLUTE = 0x00000008 +}; + + +/** + * Perform checks on @a filename. FIXME: some duplication with + * "GNUNET_DISK_"-APIs. We should unify those. + * + * @param filename file to check + * @param checks checks to perform + * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them + * fails, #GNUNET_SYSERR when a check can't be performed + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_check_filename (const char *filename, + enum GNUNET_STRINGS_FilenameCheck checks); + + +/** + * Tries to convert @a zt_addr string to an IPv6 address. + * The string is expected to have the format "[ABCD::01]:80". + * + * @param zt_addr 0-terminated string. May be mangled by the function. + * @param addrlen length of zt_addr (not counting 0-terminator). + * @param r_buf a buffer to fill. Initially gets filled with zeroes, + * then its sin6_port, sin6_family and sin6_addr are set appropriately. + * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which + * case the contents of r_buf are undefined. + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr, + size_t addrlen, + struct sockaddr_in6 *r_buf); + + +/** + * Tries to convert @a zt_addr string to an IPv4 address. + * The string is expected to have the format "1.2.3.4:80". + * + * @param zt_addr 0-terminated string. May be mangled by the function. + * @param addrlen length of zt_addr (not counting 0-terminator). + * @param r_buf a buffer to fill. + * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which case + * the contents of r_buf are undefined. + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, + size_t addrlen, + struct sockaddr_in *r_buf); + + +/** + * Parse an address given as a string into a + * `struct sockaddr`. + * + * @param addr the address + * @param[out] af set to the parsed address family (e.g. AF_INET) + * @param[out] sa set to the parsed address + * @return 0 on error, otherwise number of bytes in @a sa + */ +size_t +GNUNET_STRINGS_parse_socket_addr (const char *addr, + uint8_t *af, + struct sockaddr **sa); + + +/** + * Tries to convert @a addr string to an IP (v4 or v6) address. + * Will automatically decide whether to treat 'addr' as v4 or v6 address. + * + * @param addr a string, may not be 0-terminated. + * @param addrlen number of bytes in @a addr (if addr is 0-terminated, + * 0-terminator should not be counted towards addrlen). + * @param r_buf a buffer to fill. + * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in which + * case the contents of r_buf are undefined. + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_to_address_ip (const char *addr, + uint16_t addrlen, + struct sockaddr_storage *r_buf); + + +/** + * Returns utf-8 encoded arguments. Does nothing (returns a copy of + * @a argc and @a argv) on any platform other than W32. Returned @a + * argv has `u8argv[u8argc] == NULL`. Returned @a argv is a single + * memory block, and can be freed with a single GNUNET_free() call. + * + * @param argc argc (as given by main()) + * @param argv argv (as given by main()) + * @param u8argc a location to store new argc in (though it's th same as argc) + * @param u8argv a location to store new argv in + * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + */ +enum GNUNET_GenericReturnValue +GNUNET_STRINGS_get_utf8_args (int argc, + char *const *argv, + int *u8argc, + char *const **u8argv); + + +/** + * Like strlcpy but portable. The given string @a src is copied in full length + * (until its null byte). The destination buffer is guaranteed to be + * null-terminated. + * + * to a destination buffer + * and ensures that the destination string is null-terminated. + * + * @param dst destination of the copy + * @param src source of the copy, must be null-terminated + * @param n the length of the string to copy, including its terminating null + * byte + * @return the length of the string that was copied, excluding the terminating + * null byte + */ +size_t +GNUNET_strlcpy (char *dst, + const char *src, + size_t n); + + +/** + * Sometimes we use the binary name to determine which specific + * test to run. In those cases, the string after the last "_" + * in 'argv[0]' specifies a string that determines the configuration + * file or plugin to use. + * + * This function returns the respective substring, taking care + * of issues such as binaries ending in '.exe' on W32. + * + * @param argv0 the name of the binary + * @return string between the last '_' and the '.exe' (or the end of the string), + * NULL if argv0 has no '_' + */ +char * +GNUNET_STRINGS_get_suffix_from_binary_name (const char *argv0); + + +/* ***************** IPv4/IPv6 parsing ****************** */ + +struct GNUNET_STRINGS_PortPolicy +{ + /** + * Starting port range (0 if none given). + */ + uint16_t start_port; + + /** + * End of port range (0 if none given). + */ + uint16_t end_port; + + /** + * #GNUNET_YES if the port range should be negated + * ("!" in policy). + */ + int negate_portrange; +}; + + +/** + * @brief IPV4 network in CIDR notation. + */ +struct GNUNET_STRINGS_IPv4NetworkPolicy +{ + /** + * IPv4 address. + */ + struct in_addr network; + + /** + * IPv4 netmask. + */ + struct in_addr netmask; + + /** + * Policy for port access. + */ + struct GNUNET_STRINGS_PortPolicy pp; +}; + + +/** + * @brief network in CIDR notation for IPV6. + */ +struct GNUNET_STRINGS_IPv6NetworkPolicy +{ + /** + * IPv6 address. + */ + struct in6_addr network; + + /** + * IPv6 netmask. + */ + struct in6_addr netmask; + + /** + * Policy for port access. + */ + struct GNUNET_STRINGS_PortPolicy pp; +}; + + +/** + * Parse an IPv4 network policy. The argument specifies a list of + * subnets. The format is <tt>(network[/netmask][:[!]SPORT-DPORT];)*</tt> + * (no whitespace, must be terminated with a semicolon). The network + * must be given in dotted-decimal notation. The netmask can be given + * in CIDR notation (/16) or in dotted-decimal (/255.255.0.0). + * + * @param routeListX a string specifying the IPv4 subnets + * @return the converted list, terminated with all zeros; + * NULL if the synatx is flawed + */ +struct GNUNET_STRINGS_IPv4NetworkPolicy * +GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX); + + +/** + * Parse an IPv6 network policy. The argument specifies a list of + * subnets. The format is <tt>(network[/netmask[:[!]SPORT[-DPORT]]];)*</tt> + * (no whitespace, must be terminated with a semicolon). The network + * must be given in colon-hex notation. The netmask must be given in + * CIDR notation (/16) or can be omitted to specify a single host. + * Note that the netmask is mandatory if ports are specified. + * + * @param routeListX a string specifying the policy + * @return the converted list, 0-terminated, NULL if the synatx is flawed + */ +struct GNUNET_STRINGS_IPv6NetworkPolicy * +GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_UTIL_STRING_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_util_string.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_time_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_time_lib.h @@ -0,0 +1,931 @@ +/* + This file is part of GNUnet. + Copyright (C) 2001-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 libgnunetutil + * Multi-function utilities library for GNUnet programs + * @{ + * + * @author Christian Grothoff + * + * @file + * Functions related to time + * + * @defgroup time Time library + * Time and time calculations. + * @{ + */ + +#ifndef GNUNET_TIME_LIB_H +#define GNUNET_TIME_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_common.h" + +/** + * Time for absolute times used by GNUnet, in microseconds. + */ +struct GNUNET_TIME_Absolute +{ + /** + * The actual value. + */ + uint64_t abs_value_us; +}; + +/** + * Rounded time for timestamps used by GNUnet, in seconds. + */ +struct GNUNET_TIME_Timestamp +{ + /** + * The actual value. Must be round number in seconds. + */ + struct GNUNET_TIME_Absolute abs_time; +}; + +/** + * Time for relative time used by GNUnet, in microseconds. + * Always positive, so we can only refer to future time. + */ +struct GNUNET_TIME_Relative +{ + /** + * The actual value. + */ + uint64_t rel_value_us; +}; + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Time for relative time used by GNUnet, in microseconds and in network byte order. + */ +struct GNUNET_TIME_RelativeNBO +{ + /** + * The actual value (in network byte order). + */ + uint64_t rel_value_us__ GNUNET_PACKED; +}; + + +/** + * Time for absolute time used by GNUnet, in microseconds and in network byte order. + */ +struct GNUNET_TIME_AbsoluteNBO +{ + /** + * The actual value (in network byte order). + */ + uint64_t abs_value_us__ GNUNET_PACKED; +}; + +/** + * Time for timestamps used by GNUnet, in seconds and in network byte order. + */ +struct GNUNET_TIME_TimestampNBO +{ + /** + * The actual value. Must be round number in seconds. + */ + struct GNUNET_TIME_AbsoluteNBO abs_time_nbo; +}; + +GNUNET_NETWORK_STRUCT_END + +/** + * Relative time zero. + */ +#define GNUNET_TIME_UNIT_ZERO ((struct GNUNET_TIME_Relative){0}) + +/** + * Absolute time zero. + */ +#define GNUNET_TIME_UNIT_ZERO_ABS ((struct GNUNET_TIME_Absolute){0}) + +/** + * Timestamp of zero. + */ +#define GNUNET_TIME_UNIT_ZERO_TS ((struct GNUNET_TIME_Timestamp){{0}}) + +/** + * One microsecond, our basic time unit. + */ +#define GNUNET_TIME_UNIT_MICROSECONDS GNUNET_TIME_relative_get_unit_ () + +/** + * One millisecond. + */ +#define GNUNET_TIME_UNIT_MILLISECONDS GNUNET_TIME_relative_get_millisecond_ () + +/** + * One second. + */ +#define GNUNET_TIME_UNIT_SECONDS GNUNET_TIME_relative_get_second_ () + +/** + * One minute. + */ +#define GNUNET_TIME_UNIT_MINUTES GNUNET_TIME_relative_get_minute_ () + +/** + * One hour. + */ +#define GNUNET_TIME_UNIT_HOURS GNUNET_TIME_relative_get_hour_ () + +/** + * One day. + */ +#define GNUNET_TIME_UNIT_DAYS GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_HOURS, 24) + +/** + * One week. + */ +#define GNUNET_TIME_UNIT_WEEKS GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_DAYS, 7) + +/** + * One month (30 days). + */ +#define GNUNET_TIME_UNIT_MONTHS GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_DAYS, 30) + +/** + * One year (365 days). + */ +#define GNUNET_TIME_UNIT_YEARS GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_UNIT_DAYS, 365) + +/** + * Constant used to specify "forever". This constant + * will be treated specially in all time operations. + */ +#define GNUNET_TIME_UNIT_FOREVER_REL \ + ((struct GNUNET_TIME_Relative){UINT64_MAX}) + +/** + * Constant used to specify "forever". This constant + * will be treated specially in all time operations. + */ +#define GNUNET_TIME_UNIT_FOREVER_ABS \ + ((struct GNUNET_TIME_Absolute){UINT64_MAX}) + +/** + * Constant used to specify "forever". This constant + * will be treated specially in all time operations. + */ +#define GNUNET_TIME_UNIT_FOREVER_TS \ + ((struct GNUNET_TIME_Timestamp){{UINT64_MAX}}) + + +/** + * Threshold after which exponential backoff should not increase (15 m). + */ +#define GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) + + +/** + * Perform our standard exponential back-off calculation, starting at 1 ms + * and then going by a factor of 2 up unto a maximum of 15 m. + * + * @param r current backoff time, initially zero + */ +#define GNUNET_TIME_STD_BACKOFF(r) GNUNET_TIME_relative_min ( \ + GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD, \ + GNUNET_TIME_relative_multiply ( \ + GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, (r)), 2)) + + +/** + * Convert @a ts to human-readable timestamp. + * Note that the returned value will be overwritten if this function + * is called again. + * + * @param ts the timestamp to convert + * @return statically allocated string, will change on the next call + */ +const char * +GNUNET_TIME_timestamp2s (struct GNUNET_TIME_Timestamp ts); + + +/** + * @ingroup time + * Like `asctime`, except for GNUnet time. Converts a GNUnet internal + * absolute time (which is in UTC) to a string in local time. + * Note that the returned value will be overwritten if this function + * is called again. + * + * @param ts the absolute time to convert + * @return timestamp in human-readable form in local time + */ +const char * +GNUNET_TIME_absolute2s (struct GNUNET_TIME_Absolute ts); + + +/** + * @ingroup time + * Give relative time in human-readable fancy format. + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param delta time in milli seconds + * @param do_round are we allowed to round a bit? + * @return string in human-readable form + */ +const char * +GNUNET_TIME_relative2s (struct GNUNET_TIME_Relative delta, + bool do_round); + + +/** + * Randomized exponential back-off, starting at 1 ms + * and going up by a factor of 2+r, where 0 <= r <= 0.5, up + * to a maximum of the given threshold. + * + * @param rt current backoff time, initially zero + * @param threshold maximum value for backoff + * @return the next backoff time + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt, + struct GNUNET_TIME_Relative threshold); + + +/** + * Return a random time value between 0.5*r and 1.5*r. + * + * @param r input time for scaling + * @return randomized time + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r); + + +/** + * Return relative time of 0ms. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_zero_ (void); + + +/** + * Return absolute time of 0ms. + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_get_zero_ (void); + + +/** + * Return relative time of 1 microsecond. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_unit_ (void); + + +/** + * Return relative time of 1ms. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_millisecond_ (void); + + +/** + * Return relative time of 1s. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_second_ (void); + + +/** + * Return relative time of 1 minute. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_minute_ (void); + + +/** + * Return relative time of 1 hour. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_hour_ (void); + + +/** + * Return "forever". + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_get_forever_ (void); + + +/** + * Return "forever". + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_get_forever_ (void); + + +/** + * Get the current time. + * + * @return the current time + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_get (void); + + +/** + * Convert relative time to an absolute time in the + * future. + * + * @param rel relative time to convert + * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow) + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel); + + +/** + * Convert relative time to a timestamp in the + * future. + * + * @param rel relative time to convert + * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow) + */ +struct GNUNET_TIME_Timestamp +GNUNET_TIME_relative_to_timestamp (struct GNUNET_TIME_Relative rel); + + +/** + * Round an absolute time to a timestamp. + * + * @param at time to round + * @return the result + */ +struct GNUNET_TIME_Timestamp +GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at); + + +/** + * Get timestamp representing the current time. + * + * @return current time, rounded down to seconds + */ +struct GNUNET_TIME_Timestamp +GNUNET_TIME_timestamp_get (void); + + +/** + * Compare two absolute times. + * + * @param t1 first time + * @param op compare operator + * @param t2 second time + * @return true if @a t1 @a op @a t2 + */ +#define GNUNET_TIME_absolute_cmp(t1,op,t2) \ + ((void) (1 op 2), (t1).abs_value_us op (t2).abs_value_us) + + +/** + * Compare two timestamps + * + * @param t1 first timestamp + * @param op compare operator + * @param t2 second timestamp + * @return true if @a t1 @a op @a t2 + */ +#define GNUNET_TIME_timestamp_cmp(t1,op,t2) \ + GNUNET_TIME_absolute_cmp ((t1).abs_time,op,(t2).abs_time) + + +/** + * Compare two relative times. + * + * @param t1 first time + * @param op compare operator + * @param t2 second time + * @return true if @a t1 @a op @a t2 + */ +#define GNUNET_TIME_relative_cmp(t1,op,t2) \ + ((void) (1 op 2), (t1).rel_value_us op (t2).rel_value_us) + + +/** + * Return the minimum of two relative time values. + * + * @param t1 first timestamp + * @param t2 other timestamp + * @return timestamp that is smaller + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1, + struct GNUNET_TIME_Relative t2); + + +/** + * Return the maximum of two relative time values. + * + * @param t1 first timestamp + * @param t2 other timestamp + * @return timestamp that is larger + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1, + struct GNUNET_TIME_Relative t2); + + +/** + * Return the minimum of two absolute time values. + * + * @param t1 first timestamp + * @param t2 other timestamp + * @return timestamp that is smaller + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1, + struct GNUNET_TIME_Absolute t2); + + +/** + * Return the maximum of two absolute time values. + * + * @param t1 first timestamp + * @param t2 other timestamp + * @return timestamp that is smaller + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1, + struct GNUNET_TIME_Absolute t2); + + +/** + * Round down absolute time @a at to multiple of @a rt. + * + * @param at absolute time to round + * @param rt multiple to round to (non-zero) + * @return rounded time + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_round_down (struct GNUNET_TIME_Absolute at, + struct GNUNET_TIME_Relative rt); + + +/** + * Return the maximum of two timestamps. + * + * @param t1 first timestamp + * @param t2 other timestamp + * @return timestamp that is smaller + */ +struct GNUNET_TIME_Timestamp +GNUNET_TIME_timestamp_max (struct GNUNET_TIME_Timestamp t1, + struct GNUNET_TIME_Timestamp t2); + + +/** + * Return the minimum of two timestamps. + * + * @param t1 first timestamp + * @param t2 other timestamp + * @return timestamp that is smaller + */ +struct GNUNET_TIME_Timestamp +GNUNET_TIME_timestamp_min (struct GNUNET_TIME_Timestamp t1, + struct GNUNET_TIME_Timestamp t2); + + +/** + * Given a timestamp in the future, how much time + * remains until then? + * + * @param future some absolute time, typically in the future + * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future); + + +/** + * Test if @a a1 and @a a2 are equal within a margin of + * error of @a t. + * + * @param a1 time to compare + * @param a2 time to compare + * @param t tolerance to apply + * @return true if "|a1-a2|<=t" holds. + */ +bool +GNUNET_TIME_absolute_approx_eq (struct GNUNET_TIME_Absolute a1, + struct GNUNET_TIME_Absolute a2, + struct GNUNET_TIME_Relative t); + + +/** + * Calculate the estimate time of arrival/completion + * for an operation. + * + * @param start when did the operation start? + * @param finished how much has been done? + * @param total how much must be done overall (same unit as for "finished") + * @return remaining duration for the operation, + * assuming it continues at the same speed + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, + uint64_t finished, + uint64_t total); + + +/** + * Compute the time difference between the given start and end times. + * Use this function instead of actual subtraction to ensure that + * "FOREVER" and overflows are handled correctly. + * + * @param start some absolute time + * @param end some absolute time (typically larger or equal to start) + * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start, + struct GNUNET_TIME_Absolute end); + + +/** + * Get the duration of an operation as the + * difference of the current time and the given start time "hence". + * + * @param whence some absolute time, typically in the past + * @return 0 if hence > now, otherwise now-hence. + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence); + + +/** + * Add a given relative duration to the + * given start time. + * + * @param start some absolute time + * @param duration some relative time to add + * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start, + struct GNUNET_TIME_Relative duration); + + +/** + * Subtract a given relative duration from the + * given start time. + * + * @param start some absolute time + * @param duration some relative time to subtract + * @return ZERO if start <= duration, or FOREVER if start time is FOREVER; start-duration otherwise + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start, + struct GNUNET_TIME_Relative duration); + + +/** + * Multiply relative time by a given factor. + * + * @param rel some duration + * @param factor double to multiply with + * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_multiply_double (struct GNUNET_TIME_Relative rel, + double factor); + +/** + * Multiply relative time by a given factor. + * + * @param rel some duration + * @param factor integer to multiply with + * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel, + unsigned long long factor); + + +/** + * Saturating multiply relative time by a given factor. + * + * @param rel some duration + * @param factor integer to multiply with + * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel, + unsigned long long factor); + + +/** + * Divide relative time by a given factor. + * + * @param rel some duration + * @param factor integer to divide by + * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel, + unsigned long long factor); + + +/** + * Add relative times together. + * + * @param a1 some relative time + * @param a2 some other relative time + * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1, + struct GNUNET_TIME_Relative a2); + + +/** + * Subtract relative timestamp from the other. + * + * @param a1 first timestamp + * @param a2 second timestamp + * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1, + struct GNUNET_TIME_Relative a2); + + +/** + * Convert relative time to network byte order. + * + * @param a time to convert + * @return converted time value + */ +struct GNUNET_TIME_RelativeNBO +GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a); + + +/** + * Convert relative time from network byte order. + * + * @param a time to convert + * @return converted time value + */ +struct GNUNET_TIME_Relative +GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a); + + +/** + * Convert absolute time to network byte order. + * + * @param a time to convert + * @return converted time value + */ +struct GNUNET_TIME_AbsoluteNBO +GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a); + + +/** + * Convert timestamp to network byte order. + * + * @param t time to convert + * @return converted time value + */ +struct GNUNET_TIME_TimestampNBO +GNUNET_TIME_timestamp_hton (struct GNUNET_TIME_Timestamp t); + + +/** + * Convert milliseconds after the UNIX epoch to absolute time. + * + * @param ms_after_epoch millisecond timestamp to convert + * @return converted time value + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_from_ms (uint64_t ms_after_epoch); + + +/** + * Test if @a abs is never. + * + * @return true if it is. + */ +bool +GNUNET_TIME_absolute_is_never (struct GNUNET_TIME_Absolute abs); + + +/** + * Test if @a abs is truly in the past (excluding now). + * + * @return true if it is. + */ +bool +GNUNET_TIME_absolute_is_past (struct GNUNET_TIME_Absolute abs); + + +/** + * Test if @a abs is truly zero. + * + * @return true if it is. + */ +bool +GNUNET_TIME_absolute_is_zero (struct GNUNET_TIME_Absolute abs); + + +/** + * Test if @a abs is truly in the future (excluding now). + * + * @return true if it is. + */ +bool +GNUNET_TIME_absolute_is_future (struct GNUNET_TIME_Absolute abs); + + +/** + * Test if @a rel is forever. + * + * @return true if it is. + */ +bool +GNUNET_TIME_relative_is_forever (struct GNUNET_TIME_Relative rel); + + +/** + * Test if @a rel is zero. + * + * @return true if it is. + */ +bool +GNUNET_TIME_relative_is_zero (struct GNUNET_TIME_Relative rel); + + +/** + * Convert seconds after the UNIX epoch to absolute time. + * + * @param s_after_epoch seconds after epoch to convert + * @return converted time value + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch); + + +/** + * Convert seconds after the UNIX epoch to timestamp. + * + * @param s_after_epoch seconds after epoch to convert + * @return converted time value + */ +struct GNUNET_TIME_Timestamp +GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch); + + +/** + * Convert timestamp to number of seconds after the UNIX epoch. + * + * @param ts timestamp to convert + * @return converted time value + */ +uint64_t +GNUNET_TIME_timestamp_to_s (struct GNUNET_TIME_Timestamp ts); + + +/** + * Convert absolute time from network byte order. + * + * @param a time to convert + * @return converted time value + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a); + + +/** + * Convert timestamp from network byte order. + * + * @param tn time to convert + * @return converted time value + */ +struct GNUNET_TIME_Timestamp +GNUNET_TIME_timestamp_ntoh (struct GNUNET_TIME_TimestampNBO tn); + + +/** + * Set the timestamp offset for this instance. + * + * @param offset the offset to skew the locale time by + */ +void +GNUNET_TIME_set_offset (long long offset); + + +/** + * Get the timestamp offset for this instance. + * + * @return the offset we currently skew the locale time by + */ +long long +GNUNET_TIME_get_offset (void); + + +/** + * Return the current year (e.g. '2011'). + */ +unsigned int +GNUNET_TIME_get_current_year (void); + + +/** + * Convert a year to an expiration time of January 1st of that year. + * + * @param year a year (after 1970, please ;-)). + * @return absolute time for January 1st of that year. + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_year_to_time (unsigned int year); + + +/** + * Convert an expiration time to the respective year (rounds) + * + * @param at absolute time + * @return year a year (after 1970), 0 on error + */ +unsigned int +GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at); + + +/** + * A configuration object. + */ +struct GNUNET_CONFIGURATION_Handle; + + +/** + * Obtain the current time and make sure it is monotonically + * increasing. Guards against systems without an RTC or + * clocks running backwards and other nasty surprises. Does + * not guarantee that the returned time is near the current + * time returned by #GNUNET_TIME_absolute_get(). Two + * subsequent calls (within a short time period) may return the + * same value. Persists the last returned time on disk to + * ensure that time never goes backwards. As a result, the + * resulting value can be used to check if a message is the + * "most recent" value and replays of older messages (from + * the same origin) would be discarded. + * + * @param cfg configuration, used to determine where to + * store the time; user can also insist RTC is working + * nicely and disable the feature + * @return monotonically increasing time + */ +struct GNUNET_TIME_Absolute +GNUNET_TIME_absolute_get_monotonic ( + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_TIME_LIB_H */ +#endif + +/** @} */ /* end of group time */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_time_lib.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_application_service.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_application_service.h @@ -0,0 +1,123 @@ +/* + This file is part of GNUnet. + Copyright (C) 2010-2015, 2018, 2019 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 + * @{ + * + * @file + * Bandwidth allocation API for applications to interact with + * + * @author Christian Grothoff + * @author Matthias Wachs + * + * @defgroup TNG Transport Next Generation service + * @{ + */ +#ifndef GNUNET_TRANSPORT_APPLICATION_SERVICE_H +#define GNUNET_TRANSPORT_APPLICATION_SERVICE_H + + +#include "gnunet_constants.h" +#include "gnunet_util_lib.h" + +/** + * Handle to the TRANSPORT subsystem for making suggestions about + * connections the peer would like to have. + */ +struct GNUNET_TRANSPORT_ApplicationHandle; + + +/** + * Initialize the TRANSPORT application client handle. + * + * @param cfg configuration to use + * @return ats application handle, NULL on error + */ +struct GNUNET_TRANSPORT_ApplicationHandle * +GNUNET_TRANSPORT_application_init ( + const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Shutdown TRANSPORT application client. + * + * @param ch handle to destroy + */ +void +GNUNET_TRANSPORT_application_done ( + struct GNUNET_TRANSPORT_ApplicationHandle *ch); + + +/** + * An application would like TRANSPORT to connect to a peer. + * + * @param ch handle + * @param peer identity of the peer we need an address for + * @param pk what kind of application will the application require (can be + * #GNUNET_MQ_PRIO_BACKGROUND, we will still try to connect) + * @param bw desired bandwidth, can be zero (we will still try to connect) + * @return suggest handle, NULL if a request is already pending + */ +struct GNUNET_TRANSPORT_ApplicationSuggestHandle * +GNUNET_TRANSPORT_application_suggest ( + struct GNUNET_TRANSPORT_ApplicationHandle *ch, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_MQ_PriorityPreferences pk, + struct GNUNET_BANDWIDTH_Value32NBO bw); + + +/** + * We no longer care about being connected to a peer. + * + * @param sh handle to stop + */ +void +GNUNET_TRANSPORT_application_suggest_cancel ( + struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh); + + +/** + * An application (or a communicator) has received a HELLO (or other address + * data of another peer) and wants TRANSPORT to validate that the address is + * correct. The result is NOT returned, in fact TRANSPORT may do nothing + * (i.e. if it has too many active validations or recently tried this one + * already). If the @a addr validates, TRANSPORT will persist the address + * with PEERSTORE. + * + * @param ch handle + * @param peer identity of the peer we have an address for + * @param nt network type of @a addr (as claimed by the other peer); + * used by TRANSPORT to avoid trying @a addr's that really cannot work + * due to network type mismatches + * @param addr address to validate + */ +void +GNUNET_TRANSPORT_application_validate ( + struct GNUNET_TRANSPORT_ApplicationHandle *ch, + const struct GNUNET_PeerIdentity *peer, + enum GNUNET_NetworkType nt, + const char *addr); + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +#endif +/* end of file gnunet_ats_application_service.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_communication_service.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_communication_service.h @@ -0,0 +1,392 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2019 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 + * API of the transport service towards the communicator processes. + * + * @defgroup TNG Transport Next Generation service + * Low-level communication with other peers + * + * @see [Documentation](https://gnunet.org/transport-service) + * + * @{ + */ + +#ifndef GNUNET_TRANSPORT_COMMUNICATION_SERVICE_H +#define GNUNET_TRANSPORT_COMMUNICATION_SERVICE_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_util_lib.h" + +/** + * Version number of the transport communication API. + */ +#define GNUNET_TRANSPORT_COMMUNICATION_VERSION 0x00000000 + +/** + * Queue length + */ +#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED UINT64_MAX + +/** + * Function called by the transport service to initialize a + * message queue given address information about another peer. + * If and when the communication channel is established, the + * communicator must call #GNUNET_TRANSPORT_communicator_mq_add() + * to notify the service that the channel is now up. It is + * the responsibility of the communicator to manage sane + * retries and timeouts for any @a peer/@a address combination + * provided by the transport service. Timeouts and retries + * do not need to be signalled to the transport service. + * + * @param cls closure + * @param peer identity of the other peer + * @param address where to send the message, human-readable + * communicator-specific format, 0-terminated, UTF-8 + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is + * invalid, #GNUNET_NO if this address is already (beging) connected to. + */ +typedef int (*GNUNET_TRANSPORT_CommunicatorMqInit) ( + void *cls, + const struct GNUNET_PeerIdentity *peer, + const char *address); + + +/** + * Opaque handle to the transport service for communicators. + */ +struct GNUNET_TRANSPORT_CommunicatorHandle; + + +/** + * What characteristics does this communicator have? + * + * FIXME: may want to distinguish bi-directional as well, + * should we define a bit for that? Needed in DV logic (handle_dv_learn)! + */ +enum GNUNET_TRANSPORT_CommunicatorCharacteristics +{ + /** + * Characteristics are unknown (e.g. DV). + */ + GNUNET_TRANSPORT_CC_UNKNOWN = 0, + + /** + * Transmission is reliabile (with ACKs), e.g. TCP/HTTP/HTTPS. + */ + GNUNET_TRANSPORT_CC_RELIABLE = 1, + + /** + * Transmission is unreliable (e.g. UDP) + */ + GNUNET_TRANSPORT_CC_UNRELIABLE = 2 +}; + + +/** + * Function called when the transport service has received a + * backchannel message for this communicator (!) via a different + * return path. + * + * Typically used to receive messages of type + * #GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_FC_LIMITS or + * #GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_KX_CONFIRMATION + * as well as communicator-specific messages to assist with + * NAT traversal. + * + * @param cls closure + * @param sender which peer sent the notification + * @param msg payload + */ +typedef void (*GNUNET_TRANSPORT_CommunicatorNotify) ( + void *cls, + const struct GNUNET_PeerIdentity *sender, + const struct GNUNET_MessageHeader *msg); + + +/** + * Connect to the transport service. + * + * @param cfg configuration to use + * @param config_section_name section of the configuration to use for + * options + * @param addr_prefix address prefix for addresses supported by this + * communicator, could be NULL for incoming-only communicators + * @param cc what characteristics does the communicator have? + * @param mq_init function to call to initialize a message queue given + * the address of another peer, can be NULL if the + * communicator only supports receiving messages + * @param mq_init_cls closure for @a mq_init + * @param notify_cb function to pass backchannel messages to communicator + * @param notify_cb_cls closure for @a notify_cb + * @return NULL on error + */ +struct GNUNET_TRANSPORT_CommunicatorHandle * +GNUNET_TRANSPORT_communicator_connect ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *config_section_name, + const char *addr_prefix, + enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, + GNUNET_TRANSPORT_CommunicatorMqInit mq_init, + void *mq_init_cls, + GNUNET_TRANSPORT_CommunicatorNotify notify_cb, + void *notify_cb_cls); + + +/** + * Disconnect from the transport service. + * + * @param ch handle returned from connect + */ +void +GNUNET_TRANSPORT_communicator_disconnect ( + struct GNUNET_TRANSPORT_CommunicatorHandle *ch); + + +/* ************************* Receiving *************************** */ + +/** + * Function called to notify communicator that we have received + * and processed the message. Used for flow control (if supported + * by the communicator). + * + * @param cls closure + * @param success #GNUNET_SYSERR on failure (try to disconnect/reset connection) + * #GNUNET_OK on success + */ +typedef void +(*GNUNET_TRANSPORT_MessageCompletedCallback) (void *cls, + int success); + + +/** + * Notify transport service that the communicator has received + * a message. + * + * @param handle connection to transport service + * @param sender presumed sender of the message (details to be checked + * by higher layers) + * @param msg the message + * @param expected_addr_validity how long does the communicator believe it + * will continue to be able to receive messages from the same address + * on which it received this message? + * @param cb function to call once handling the message is done, NULL if + * flow control is not supported by this communicator + * @param cb_cls closure for @a cb + * @return #GNUNET_OK if all is well, #GNUNET_NO if the message was + * immediately dropped due to memory limitations (communicator + * should try to apply back pressure), + * #GNUNET_SYSERR if the message could not be delivered because + * the transport service is not yet up + */ +int +GNUNET_TRANSPORT_communicator_receive ( + struct GNUNET_TRANSPORT_CommunicatorHandle *handle, + const struct GNUNET_PeerIdentity *sender, + const struct GNUNET_MessageHeader *msg, + struct GNUNET_TIME_Relative expected_addr_validity, + GNUNET_TRANSPORT_MessageCompletedCallback cb, + void *cb_cls); + + +/* ************************* Discovery *************************** */ + +/** + * Handle returned to identify the internal data structure the transport + * API has created to manage a message queue to a particular peer. + */ +struct GNUNET_TRANSPORT_QueueHandle; + + +/** + * Possible states of a connection. + */ +enum GNUNET_TRANSPORT_ConnectionStatus +{ + /** + * Connection is down. + */ + GNUNET_TRANSPORT_CS_DOWN = -1, + + /** + * this is an outbound connection (transport initiated) + */ + GNUNET_TRANSPORT_CS_OUTBOUND = 0, + + /** + * this is an inbound connection (communicator initiated) + */ + GNUNET_TRANSPORT_CS_INBOUND = 1 +}; + + +/** + * Notify transport service that a MQ became available due to an + * "inbound" connection or because the communicator discovered the + * presence of another peer. + * + * @param ch connection to transport service + * @param peer peer with which we can now communicate + * @param address address in human-readable format, 0-terminated, UTF-8 + * @param mtu maximum message size supported by queue, 0 if + * sending is not supported, SIZE_MAX for no MTU + * @param q_len number of messages that can be send through this queue + * @param priority queue priority. Queues with highest priority should be + * used + * @param nt which network type does the @a address belong to? + * @param cs what is the connection status of the queue? + * @param mq message queue of the @a peer + * @return API handle identifying the new MQ + */ +struct GNUNET_TRANSPORT_QueueHandle * +GNUNET_TRANSPORT_communicator_mq_add ( + struct GNUNET_TRANSPORT_CommunicatorHandle *ch, + const struct GNUNET_PeerIdentity *peer, + const char *address, + uint32_t mtu, + uint64_t q_len, + uint32_t priority, + enum GNUNET_NetworkType nt, + enum GNUNET_TRANSPORT_ConnectionStatus cs, + struct GNUNET_MQ_Handle *mq); + +/** + * Notify transport service that an MQ was updated + * + * @param ch connection to transport service + * @param u_qh the queue to update + * @param q_len number of messages that can be send through this queue + * @param priority queue priority. Queues with highest priority should be + * used + */ +void +GNUNET_TRANSPORT_communicator_mq_update ( + struct GNUNET_TRANSPORT_CommunicatorHandle *ch, + const struct GNUNET_TRANSPORT_QueueHandle *u_qh, + uint64_t q_len, + uint32_t priority); + +/** + * Notify transport service that an MQ became unavailable due to a + * disconnect or timeout. + * + * @param qh handle for the queue that must be invalidated + */ +void +GNUNET_TRANSPORT_communicator_mq_del (struct GNUNET_TRANSPORT_QueueHandle *qh); + + +/** + * Internal representation of an address a communicator is + * currently providing for the transport service. + */ +struct GNUNET_TRANSPORT_AddressIdentifier; + + +/** + * Notify transport service about an address that this communicator + * provides for this peer. + * + * @param ch connection to transport service + * @param address our address in human-readable format, 0-terminated, UTF-8 + * @param nt which network type does the address belong to? + * @param expiration when does the communicator forsee this address expiring? + */ +struct GNUNET_TRANSPORT_AddressIdentifier * +GNUNET_TRANSPORT_communicator_address_add ( + struct GNUNET_TRANSPORT_CommunicatorHandle *ch, + const char *address, + enum GNUNET_NetworkType nt, + struct GNUNET_TIME_Relative expiration); + + +/** + * Notify transport service about an address that this communicator + * no longer provides for this peer. + * + * @param ai address that is no longer provided + */ +void +GNUNET_TRANSPORT_communicator_address_remove ( + struct GNUNET_TRANSPORT_AddressIdentifier *ai); + +/** + * Notify transport service that this communicator no longer provides all its addresses for this peer. + * + * @param ch The communicator handle. + */ +void +GNUNET_TRANSPORT_communicator_address_remove_all ( + struct GNUNET_TRANSPORT_CommunicatorHandle *ch); + +/** + * The communicator asks the transport service to route a message via + * a different path to another communicator service at another peer. + * This must only be done for special control traffic (as there is no + * flow control for this API), such as acknowledgements, and generally + * only be done if the communicator is uni-directional (i.e. cannot + * send the message back itself). + * + * While backchannel messages are signed and encrypted, communicators + * must protect against replay attacks when using this backchannel + * communication! + * + * @param ch handle of this communicator + * @param pid peer to send the message to + * @param comm name of the communicator to send the message to + * @param header header of the message to transmit and pass via the + * notify-API to @a pid's communicator @a comm + */ +void +GNUNET_TRANSPORT_communicator_notify ( + struct GNUNET_TRANSPORT_CommunicatorHandle *ch, + const struct GNUNET_PeerIdentity *pid, + const char *comm, + const struct GNUNET_MessageHeader *header); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_TRANSPORT_COMMUNICATOR_SERVICE_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_transport_communicator_service.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_core_service.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_core_service.h @@ -0,0 +1,183 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2019 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 + * API of the transport service towards the CORE service (TNG version) + * + * @defgroup TNG Transport Next Generation service + * Communication with other peers + * + * @see [Documentation](https://gnunet.org/transport-service) + * + * @{ + */ +#ifndef GNUNET_TRANSPORT_CORE_SERVICE_H +#define GNUNET_TRANSPORT_CORE_SERVICE_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_util_lib.h" + +/** + * Version number of the transport API. + */ +#define GNUNET_TRANSPORT_CORE_VERSION 0x00000000 + + +/** + * Opaque handle to the service. + */ +struct GNUNET_TRANSPORT_CoreHandle; + + +/** + * Function called to notify transport users that another + * peer connected to us. + * + * @param cls closure + * @param peer the identity of the peer that connected; this + * pointer will remain valid until the disconnect, hence + * applications do not necessarily have to make a copy + * of the value if they only need it until disconnect + * @param mq message queue to use to transmit to @a peer + * @return closure to use in MQ handlers + */ +typedef void *(*GNUNET_TRANSPORT_NotifyConnect) ( + void *cls, + const struct GNUNET_PeerIdentity *peer, + struct GNUNET_MQ_Handle *mq); + + +/** + * Function called to notify transport users that another peer + * disconnected from us. The message queue that was given to the + * connect notification will be destroyed and must not be used + * henceforth. + * + * @param cls closure from #GNUNET_TRANSPORT_core_connect + * @param peer the peer that disconnected + * @param handlers_cls closure of the handlers, was returned from the + * connect notification callback + */ +typedef void (*GNUNET_TRANSPORT_NotifyDisconnect) ( + void *cls, + const struct GNUNET_PeerIdentity *peer, + void *handler_cls); + + +/** + * Connect to the transport service. Note that the connection may + * complete (or fail) asynchronously. + * + * @param cfg configuration to use + * @param self our own identity (API should check that it matches + * the identity found by transport), or NULL (no check) + * @param handlers array of message handlers; note that the + * closures provided will be ignored and replaced + * with the respective return value from @a nc + * @param handlers array with handlers to call when we receive messages, or NULL + * @param cls closure for the @a nc, @a nd and @a neb callbacks + * @param nc function to call on connect events, or NULL + * @param nd function to call on disconnect events, or NULL + * @param neb function to call if we have excess bandwidth to a peer, or NULL + * @return NULL on error + */ +struct GNUNET_TRANSPORT_CoreHandle * +GNUNET_TRANSPORT_core_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *self, + const struct GNUNET_MQ_MessageHandler *handlers, + void *cls, + GNUNET_TRANSPORT_NotifyConnect nc, + GNUNET_TRANSPORT_NotifyDisconnect nd); + + +/** + * Disconnect from the transport service. + * + * @param handle handle returned from connect + */ +void +GNUNET_TRANSPORT_core_disconnect (struct GNUNET_TRANSPORT_CoreHandle *handle); + + +/** + * Notification from the CORE service to the TRANSPORT service + * that the CORE service has finished processing a message from + * TRANSPORT (via the @code{handlers} of #GNUNET_TRANSPORT_core_connect()) + * and that it is thus now OK for TRANSPORT to send more messages + * for @a pid. + * + * Used to provide flow control, this is our equivalent to + * #GNUNET_SERVICE_client_continue() of an ordinary service. + * + * Note that due to the use of a window, TRANSPORT may send multiple + * messages destined for the same peer even without an intermediate + * call to this function. However, CORE must still call this function + * once per message received, as otherwise eventually the window will + * be full and TRANSPORT will stop providing messages to CORE for @a + * pid. + * + * @param ch core handle + * @param pid which peer was the message from that was fully processed by CORE + */ +void +GNUNET_TRANSPORT_core_receive_continue (struct GNUNET_TRANSPORT_CoreHandle *ch, + const struct GNUNET_PeerIdentity *pid); + + +/** + * Checks if a given peer is connected to us and get the message queue. + * Convenience function. + * + * @param handle connection to transport service + * @param peer the peer to check + * @return NULL if disconnected, otherwise message queue for @a peer + */ +struct GNUNET_MQ_Handle * +GNUNET_TRANSPORT_core_get_mq (struct GNUNET_TRANSPORT_CoreHandle *handle, + const struct GNUNET_PeerIdentity *peer); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_TRANSPORT_CORE_SERVICE_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_transport_core_service.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_monitor_service.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_transport_monitor_service.h @@ -0,0 +1,197 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2016 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 + * Monitoring / diagnostics API for the transport service + * + * @defgroup TNG Transport Next Generation service + * Communication with other peers + * + * @see [Documentation](https://gnunet.org/transport-service) + * + * @{ + */ +#ifndef GNUNET_TRANSPORT_MONITOR_SERVICE_H +#define GNUNET_TRANSPORT_MONITOR_SERVICE_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +#include "gnunet_util_lib.h" +#include "gnunet_transport_communication_service.h" + + +/** + * Version number of the transport API. + */ +#define GNUNET_TRANSPORT_MONITOR_VERSION 0x00000000 + + +/** + * Information about another peer's address. + */ +struct GNUNET_TRANSPORT_MonitorInformation +{ + /** + * Address we have for the peer, human-readable, 0-terminated, in UTF-8. + */ + const char *address; + + /** + * Network type of the address. + */ + enum GNUNET_NetworkType nt; + + /** + * Connection status. + */ + enum GNUNET_TRANSPORT_ConnectionStatus cs; + + /** + * Number of messages pending transmission for this @e address. + */ + uint32_t num_msg_pending; + + /** + * Number of bytes pending transmission for this @e address. + */ + uint32_t num_bytes_pending; + + /** + * When was this address last validated. + */ + struct GNUNET_TIME_Absolute last_validation; + + /** + * When does this address expire. + */ + struct GNUNET_TIME_Absolute valid_until; + + /** + * Time of the next validation operation. + */ + struct GNUNET_TIME_Absolute next_validation; + + /** + * Current estimate of the RTT. + */ + struct GNUNET_TIME_Relative rtt; +}; + + +/** + * Function to call with information about a peer. + * + * If one_shot was set to #GNUNET_YES to iterate over all peers once, + * a final call with NULL for peer and address will follow when done. + * In this case state and timeout do not contain valid values. + * + * The #GNUNET_TRANSPORT_monitor_peers_cancel() call MUST not be called from + * within this function! + * + * + * @param cls closure + * @param peer peer this update is about, + * NULL if this is the final last callback for a iteration operation + * @param mi monitoring data on the peer + */ +typedef void +(*GNUNET_TRANSPORT_MonitorCallback) (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct + GNUNET_TRANSPORT_MonitorInformation *mi); + + +/** + * Handle for a #GNUNET_TRANSPORT_monitor() operation. + */ +struct GNUNET_TRANSPORT_MonitorContext; + + +/** + * Return information about a specific peer or all peers currently known to + * transport service once or in monitoring mode. To obtain information about + * a specific peer, a peer identity can be passed. To obtain information about + * all peers currently known to transport service, NULL can be passed as peer + * identity. + * + * For each peer, the callback is called with information about the address used + * to communicate with this peer, the state this peer is currently in and the + * the current timeout for this state. + * + * Upon completion, the #GNUNET_TRANSPORT_PeerIterateCallback is called one + * more time with `NULL`. After this, the operation must no longer be + * explicitly canceled. + * + * The #GNUNET_TRANSPORT_monitor_peers_cancel call MUST not be called in the + * the peer_callback! + * + * @param cfg configuration to use + * @param peer a specific peer identity to obtain information for, + * NULL for all peers + * @param one_shot #GNUNET_YES to return the current state and then end (with NULL+NULL), + * #GNUNET_NO to monitor peers continuously + * @param cb function to call with the results + * @param cb_cls closure for @a mc + */ +struct GNUNET_TRANSPORT_MonitorContext * +GNUNET_TRANSPORT_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *peer, + int one_shot, + GNUNET_TRANSPORT_MonitorCallback cb, + void *cb_cls); + + +/** + * Cancel request to monitor peers + * + * @param mc handle for the request to cancel + */ +void +GNUNET_TRANSPORT_monitor_cancel (struct GNUNET_TRANSPORT_MonitorContext *mc); + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef GNUNET_TRANSPORT_MONITOR_SERVICE_H */ +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ + +/* end of gnunet_transport_monitor_service.h */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_tun_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_tun_lib.h @@ -0,0 +1,977 @@ +/* + This file is part of GNUnet. + Copyright (C) 2010-2013 Christian Grothoff + + 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 vpn_suite VPN services and libraries + * @{ + * + * @author Philipp Toelke + * @author Christian Grothoff + * + * @file + * Standard TCP/IP network structs and IP checksum calculations for TUN + * interaction + * + * @defgroup tun TUN library + * Standard TCP/IP network structs and IP checksum calculations for TUN + * interaction + * @{ + */ +#ifndef GNUNET_TUN_LIB_H +#define GNUNET_TUN_LIB_H + + +/* see http://www.iana.org/assignments/ethernet-numbers */ +#ifndef ETH_P_IPV4 +/** + * Number for IPv4 + */ +#define ETH_P_IPV4 0x0800 +#endif + +#ifndef ETH_P_IPV6 +/** + * Number for IPv6 + */ +#define ETH_P_IPV6 0x86DD +#endif + + +/** + * Maximum regex string length for use with #GNUNET_TUN_ipv4toregexsearch. + * + * 8 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-", + * one byte for 0-termination. + */ + +#define GNUNET_TUN_IPV4_REGEXLEN 16 + + +/** + * Maximum regex string length for use with #GNUNET_TUN_ipv6toregexsearch + * + * 32 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-", + * one byte for 0-termination. + */ +#define GNUNET_TUN_IPV6_REGEXLEN 40 + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Header from Linux TUN interface. + */ +struct GNUNET_TUN_Layer2PacketHeader +{ + /** + * Some flags (unused). + */ + uint16_t flags GNUNET_PACKED; + + /** + * Here we get an ETH_P_-number. + */ + uint16_t proto GNUNET_PACKED; +}; + + +/** + * Standard IPv4 header. + */ +struct GNUNET_TUN_IPv4Header +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int header_length : 4 GNUNET_PACKED; + unsigned int version : 4 GNUNET_PACKED; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned int version : 4 GNUNET_PACKED; + unsigned int header_length : 4 GNUNET_PACKED; +#else +#error byteorder undefined +#endif + uint8_t diff_serv; + + /** + * Length of the packet, including this header. + */ + uint16_t total_length GNUNET_PACKED; + + /** + * Unique random ID for matching up fragments. + */ + uint16_t identification GNUNET_PACKED; + + unsigned int flags : 3 GNUNET_PACKED; + + unsigned int fragmentation_offset : 13 GNUNET_PACKED; + + /** + * How many more hops can this packet be forwarded? + */ + uint8_t ttl; + + /** + * L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP. + */ + uint8_t protocol; + + /** + * Checksum. + */ + uint16_t checksum GNUNET_PACKED; + + /** + * Origin of the packet. + */ + struct in_addr source_address; + + /** + * Destination of the packet. + */ + struct in_addr destination_address; +} GNUNET_GCC_STRUCT_LAYOUT; + + +/** + * Standard IPv6 header. + */ +struct GNUNET_TUN_IPv6Header +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int traffic_class_h : 4 GNUNET_PACKED; + unsigned int version : 4 GNUNET_PACKED; + unsigned int traffic_class_l : 4 GNUNET_PACKED; + unsigned int flow_label : 20 GNUNET_PACKED; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned int version : 4 GNUNET_PACKED; + unsigned int traffic_class : 8 GNUNET_PACKED; + unsigned int flow_label : 20 GNUNET_PACKED; +#else +#error byteorder undefined +#endif + /** + * Length of the payload, excluding this header. + */ + uint16_t payload_length GNUNET_PACKED; + + /** + * For example, IPPROTO_UDP or IPPROTO_TCP. + */ + uint8_t next_header; + + /** + * How many more hops can this packet be forwarded? + */ + uint8_t hop_limit; + + /** + * Origin of the packet. + */ + struct in6_addr source_address GNUNET_PACKED; + + /** + * Destination of the packet. + */ + struct in6_addr destination_address GNUNET_PACKED; +} GNUNET_GCC_STRUCT_LAYOUT; + + +/** + * TCP flags. + */ +#define GNUNET_TUN_TCP_FLAGS_FIN 1 +#define GNUNET_TUN_TCP_FLAGS_SYN 2 +#define GNUNET_TUN_TCP_FLAGS_RST 4 +#define GNUNET_TUN_TCP_FLAGS_PSH 8 +#define GNUNET_TUN_TCP_FLAGS_ACK 16 +#define GNUNET_TUN_TCP_FLAGS_URG 32 +#define GNUNET_TUN_TCP_FLAGS_ECE 64 +#define GNUNET_TUN_TCP_FLAGS_CWR 128 + +/** + * TCP packet header. + */ +struct GNUNET_TUN_TcpHeader +{ + /** + * Source port (in NBO). + */ + uint16_t source_port GNUNET_PACKED; + + /** + * Destination port (in NBO). + */ + uint16_t destination_port GNUNET_PACKED; + + /** + * Sequence number. + */ + uint32_t seq GNUNET_PACKED; + + /** + * Acknowledgement number. + */ + uint32_t ack GNUNET_PACKED; +#if __BYTE_ORDER == __LITTLE_ENDIAN + /** + * Reserved. Must be zero. + */ + unsigned int reserved : 4 GNUNET_PACKED; + /** + * Number of 32-bit words in TCP header. + */ + unsigned int off : 4 GNUNET_PACKED; +#elif __BYTE_ORDER == __BIG_ENDIAN + /** + * Number of 32-bit words in TCP header. + */ + unsigned int off : 4 GNUNET_PACKED; + /** + * Reserved. Must be zero. + */ + unsigned int reserved : 4 GNUNET_PACKED; +#else +#error byteorder undefined +#endif + + /** + * Flags (SYN, FIN, ACK, etc.) + */ + uint8_t flags; + + /** + * Window size. + */ + uint16_t window_size GNUNET_PACKED; + + /** + * Checksum. + */ + uint16_t crc GNUNET_PACKED; + + /** + * Urgent pointer. + */ + uint16_t urgent_pointer GNUNET_PACKED; +} GNUNET_GCC_STRUCT_LAYOUT; + + +/** + * UDP packet header. + */ +struct GNUNET_TUN_UdpHeader +{ + /** + * Source port (in NBO). + */ + uint16_t source_port GNUNET_PACKED; + + /** + * Destination port (in NBO). + */ + uint16_t destination_port GNUNET_PACKED; + + /** + * Number of bytes of payload. + */ + uint16_t len GNUNET_PACKED; + + /** + * Checksum. + */ + uint16_t crc GNUNET_PACKED; +}; + + +/** + * A few common DNS classes (ok, only one is common, but I list a + * couple more to make it clear what we're talking about here). + */ +#define GNUNET_TUN_DNS_CLASS_INTERNET 1 +#define GNUNET_TUN_DNS_CLASS_CHAOS 3 +#define GNUNET_TUN_DNS_CLASS_HESIOD 4 + +#define GNUNET_TUN_DNS_OPCODE_QUERY 0 +#define GNUNET_TUN_DNS_OPCODE_INVERSE_QUERY 1 +#define GNUNET_TUN_DNS_OPCODE_STATUS 2 + + +/** + * RFC 1035 codes. + */ +#define GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR 0 +#define GNUNET_TUN_DNS_RETURN_CODE_FORMAT_ERROR 1 +#define GNUNET_TUN_DNS_RETURN_CODE_SERVER_FAILURE 2 +#define GNUNET_TUN_DNS_RETURN_CODE_NAME_ERROR 3 +#define GNUNET_TUN_DNS_RETURN_CODE_NOT_IMPLEMENTED 4 +#define GNUNET_TUN_DNS_RETURN_CODE_REFUSED 5 + +/** + * RFC 2136 codes + */ +#define GNUNET_TUN_DNS_RETURN_CODE_YXDOMAIN 6 +#define GNUNET_TUN_DNS_RETURN_CODE_YXRRSET 7 +#define GNUNET_TUN_DNS_RETURN_CODE_NXRRSET 8 +#define GNUNET_TUN_DNS_RETURN_CODE_NOT_AUTH 9 +#define GNUNET_TUN_DNS_RETURN_CODE_NOT_ZONE 10 + + +/** + * DNS flags (largely RFC 1035 / RFC 2136). + */ +struct GNUNET_TUN_DnsFlags +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + /** + * Set to 1 if recursion is desired (client -> server) + */ + unsigned int recursion_desired : 1 GNUNET_PACKED; + + /** + * Set to 1 if message is truncated + */ + unsigned int message_truncated : 1 GNUNET_PACKED; + + /** + * Set to 1 if this is an authoritative answer + */ + unsigned int authoritative_answer : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_OPCODE_ defines. + */ + unsigned int opcode : 4 GNUNET_PACKED; + + /** + * query:0, response:1 + */ + unsigned int query_or_response : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_RETURN_CODE_ defines. + */ + unsigned int return_code : 4 GNUNET_PACKED; + + /** + * See RFC 4035. + */ + unsigned int checking_disabled : 1 GNUNET_PACKED; + + /** + * Response has been cryptographically verified, RFC 4035. + */ + unsigned int authenticated_data : 1 GNUNET_PACKED; + + /** + * Always zero. + */ + unsigned int zero : 1 GNUNET_PACKED; + + /** + * Set to 1 if recursion is available (server -> client) + */ + unsigned int recursion_available : 1 GNUNET_PACKED; +#elif __BYTE_ORDER == __BIG_ENDIAN + /** + * query:0, response:1 + */ + unsigned int query_or_response : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_OPCODE_ defines. + */ + unsigned int opcode : 4 GNUNET_PACKED; + + /** + * Set to 1 if this is an authoritative answer + */ + unsigned int authoritative_answer : 1 GNUNET_PACKED; + + /** + * Set to 1 if message is truncated + */ + unsigned int message_truncated : 1 GNUNET_PACKED; + + /** + * Set to 1 if recursion is desired (client -> server) + */ + unsigned int recursion_desired : 1 GNUNET_PACKED; + + + /** + * Set to 1 if recursion is available (server -> client) + */ + unsigned int recursion_available : 1 GNUNET_PACKED; + + /** + * Always zero. + */ + unsigned int zero : 1 GNUNET_PACKED; + + /** + * Response has been cryptographically verified, RFC 4035. + */ + unsigned int authenticated_data : 1 GNUNET_PACKED; + + /** + * See RFC 4035. + */ + unsigned int checking_disabled : 1 GNUNET_PACKED; + + /** + * See GNUNET_TUN_DNS_RETURN_CODE_ defines. + */ + unsigned int return_code : 4 GNUNET_PACKED; +#else +#error byteorder undefined +#endif +} GNUNET_GCC_STRUCT_LAYOUT; + + +/** + * DNS header. + */ +struct GNUNET_TUN_DnsHeader +{ + /** + * Unique identifier for the request/response. + */ + uint16_t id GNUNET_PACKED; + + /** + * Flags. + */ + struct GNUNET_TUN_DnsFlags flags; + + /** + * Number of queries. + */ + uint16_t query_count GNUNET_PACKED; + + /** + * Number of answers. + */ + uint16_t answer_rcount GNUNET_PACKED; + + /** + * Number of authoritative answers. + */ + uint16_t authority_rcount GNUNET_PACKED; + + /** + * Number of additional records. + */ + uint16_t additional_rcount GNUNET_PACKED; +}; + + +/** + * Payload of DNS SOA record (header). + */ +struct GNUNET_TUN_DnsSoaRecord +{ + /** + * The version number of the original copy of the zone. (NBO) + */ + uint32_t serial GNUNET_PACKED; + + /** + * Time interval before the zone should be refreshed. (NBO) + */ + uint32_t refresh GNUNET_PACKED; + + /** + * Time interval that should elapse before a failed refresh should + * be retried. (NBO) + */ + uint32_t retry GNUNET_PACKED; + + /** + * Time value that specifies the upper limit on the time interval + * that can elapse before the zone is no longer authoritative. (NBO) + */ + uint32_t expire GNUNET_PACKED; + + /** + * The bit minimum TTL field that should be exported with any RR + * from this zone. (NBO) + */ + uint32_t minimum GNUNET_PACKED; +}; + + +/** + * Payload of DNS SRV record (header). + */ +struct GNUNET_TUN_DnsSrvRecord +{ + /** + * Preference for this entry (lower value is higher preference). Clients + * will contact hosts from the lowest-priority group first and fall back + * to higher priorities if the low-priority entries are unavailable. (NBO) + */ + uint16_t prio GNUNET_PACKED; + + /** + * Relative weight for records with the same priority. Clients will use + * the hosts of the same (lowest) priority with a probability proportional + * to the weight given. (NBO) + */ + uint16_t weight GNUNET_PACKED; + + /** + * TCP or UDP port of the service. (NBO) + */ + uint16_t port GNUNET_PACKED; + + /* followed by 'target' name */ +}; + + +/** + * Payload of DNS URI record (header). + */ +struct GNUNET_TUN_DnsUriRecord +{ + /** + * Preference for this entry (lower value is higher preference). Clients + * will contact hosts from the lowest-priority group first and fall back + * to higher priorities if the low-priority entries are unavailable. (NBO) + */ + uint16_t prio GNUNET_PACKED; + + /** + * Relative weight for records with the same priority. Clients will use + * the hosts of the same (lowest) priority with a probability proportional + * to the weight given. (NBO) + */ + uint16_t weight GNUNET_PACKED; + + /* followed by 'target' name */ +}; + + +/** + * Payload of DNS CERT record. + */ +struct GNUNET_TUN_DnsCertRecord +{ + /** + * Certificate type + */ + uint16_t cert_type; + + /** + * Certificate KeyTag + */ + uint16_t cert_tag; + + /** + * Algorithm + */ + uint8_t algorithm; + + /* Followed by the certificate */ +}; + + +/** + * Payload of DNSSEC TLSA record. + * http://datatracker.ietf.org/doc/draft-ietf-dane-protocol/ + */ +struct GNUNET_TUN_DnsTlsaRecord +{ + /** + * Certificate usage + * 0: CA cert + * 1: Entity cert + * 2: Trust anchor + * 3: domain-issued cert + */ + uint8_t usage; + + /** + * Selector + * What part will be matched against the cert + * presented by server + * 0: Full cert (in binary) + * 1: Full cert (in DER) + */ + uint8_t selector; + + /** + * Matching type (of selected content) + * 0: exact match + * 1: SHA-256 hash + * 2: SHA-512 hash + */ + uint8_t matching_type; + + /** + * followed by certificate association data + * The "certificate association data" to be matched. + * These bytes are either raw data (that is, the full certificate or + * its SubjectPublicKeyInfo, depending on the selector) for matching + * type 0, or the hash of the raw data for matching types 1 and 2. + * The data refers to the certificate in the association, not to the + * TLS ASN.1 Certificate object. + * + * The data is represented as a string of hex chars + */ +}; + + +/** + * Payload of GNS VPN record + */ +struct GNUNET_TUN_GnsVpnRecord +{ + /** + * The peer to contact + */ + struct GNUNET_PeerIdentity peer; + + /** + * The protocol to use + */ + uint16_t proto; + + /* followed by the servicename */ +}; + + +/** + * DNS query prefix. + */ +struct GNUNET_TUN_DnsQueryLine +{ + /** + * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) + */ + uint16_t type GNUNET_PACKED; + + /** + * Desired class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO) + */ + uint16_t dns_traffic_class GNUNET_PACKED; +}; + + +/** + * General DNS record prefix. + */ +struct GNUNET_TUN_DnsRecordLine +{ + /** + * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) + */ + uint16_t type GNUNET_PACKED; + + /** + * Record class (usually GNUNET_TUN_DNS_CLASS_INTERNET). (NBO) + */ + uint16_t dns_traffic_class GNUNET_PACKED; + + /** + * Expiration for the record (in seconds). (NBO) + */ + uint32_t ttl GNUNET_PACKED; + + /** + * Number of bytes of data that follow. (NBO) + */ + uint16_t data_len GNUNET_PACKED; +}; + + +#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY 0 +#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE 3 +#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH 4 +#define GNUNET_TUN_ICMPTYPE_REDIRECT_MESSAGE 5 +#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST 8 +#define GNUNET_TUN_ICMPTYPE_ROUTER_ADVERTISEMENT 9 +#define GNUNET_TUN_ICMPTYPE_ROUTER_SOLICITATION 10 +#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED 11 + +#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE 1 +#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG 2 +#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED 3 +#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM 4 +#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST 128 +#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY 129 + + +/** + * ICMP header. + */ +struct GNUNET_TUN_IcmpHeader +{ + uint8_t type; + uint8_t code; + uint16_t crc GNUNET_PACKED; + + union + { + /** + * ICMP Echo (request/reply) + */ + struct + { + uint16_t identifier GNUNET_PACKED; + uint16_t sequence_number GNUNET_PACKED; + } echo; + + /** + * ICMP Destination Unreachable (RFC 1191) + */ + struct ih_pmtu + { + uint16_t empty GNUNET_PACKED; + uint16_t next_hop_mtu GNUNET_PACKED; + /* followed by original IP header + first 8 bytes of original IP datagram + */ + } destination_unreachable; + + /** + * ICMP Redirect + */ + struct in_addr redirect_gateway_address; + + /** + * MTU for packets that are too big (IPv6). + */ + uint32_t packet_too_big_mtu GNUNET_PACKED; + } quench; +}; + + +GNUNET_NETWORK_STRUCT_END + + +/** + * Initialize an IPv4 header. + * + * @param ip header to initialize + * @param protocol protocol to use (e.g. IPPROTO_UDP) + * @param payload_length number of bytes of payload that follow (excluding IPv4 + * header) + * @param src source IP address to use + * @param dst destination IP address to use + */ +void +GNUNET_TUN_initialize_ipv4_header (struct GNUNET_TUN_IPv4Header *ip, + uint8_t protocol, + uint16_t payload_length, + const struct in_addr *src, + const struct in_addr *dst); + + +/** + * Initialize an IPv6 header. + * + * @param ip header to initialize + * @param protocol protocol to use (e.g. IPPROTO_UDP) + * @param payload_length number of bytes of payload that follow (excluding IPv4 + * header) + * @param src source IP address to use + * @param dst destination IP address to use + */ +void +GNUNET_TUN_initialize_ipv6_header (struct GNUNET_TUN_IPv6Header *ip, + uint8_t protocol, + uint16_t payload_length, + const struct in6_addr *src, + const struct in6_addr *dst); + +/** + * Calculate IPv4 TCP checksum. + * + * @param ip ipv4 header fully initialized + * @param tcp TCP header (initialized except for CRC) + * @param payload the TCP payload + * @param payload_length number of bytes of TCP @a payload + */ +void +GNUNET_TUN_calculate_tcp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, + struct GNUNET_TUN_TcpHeader *tcp, + const void *payload, + uint16_t payload_length); + +/** + * Calculate IPv6 TCP checksum. + * + * @param ip ipv6 header fully initialized + * @param tcp TCP header (initialized except for CRC) + * @param payload the TCP payload + * @param payload_length number of bytes of TCP payload + */ +void +GNUNET_TUN_calculate_tcp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, + struct GNUNET_TUN_TcpHeader *tcp, + const void *payload, + uint16_t payload_length); + +/** + * Calculate IPv4 UDP checksum. + * + * @param ip ipv4 header fully initialized + * @param udp UDP header (initialized except for CRC) + * @param payload the UDP payload + * @param payload_length number of bytes of UDP @a payload + */ +void +GNUNET_TUN_calculate_udp4_checksum (const struct GNUNET_TUN_IPv4Header *ip, + struct GNUNET_TUN_UdpHeader *udp, + const void *payload, + uint16_t payload_length); + + +/** + * Calculate IPv6 UDP checksum. + * + * @param ip ipv6 header fully initialized + * @param udp UDP header (initialized except for CRC) + * @param payload the UDP payload + * @param payload_length number of bytes of @a payload + */ +void +GNUNET_TUN_calculate_udp6_checksum (const struct GNUNET_TUN_IPv6Header *ip, + struct GNUNET_TUN_UdpHeader *udp, + const void *payload, + uint16_t payload_length); + + +/** + * Calculate ICMP checksum. + * + * @param icmp IMCP header (initialized except for CRC) + * @param payload the ICMP payload + * @param payload_length number of bytes of @a payload + */ +void +GNUNET_TUN_calculate_icmp_checksum (struct GNUNET_TUN_IcmpHeader *icmp, + const void *payload, + uint16_t payload_length); + + +/** + * Create a regex in @a rxstr from the given @a ip and @a port. + * + * @param ip IPv4 representation. + * @param port destination port + * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV4_REGEXLEN + * bytes long. + */ +void +GNUNET_TUN_ipv4toregexsearch (const struct in_addr *ip, + uint16_t port, + char *rxstr); + + +/** + * Create a regex in @a rxstr from the given @a ipv6 and @a port. + * + * @param ipv6 IPv6 representation. + * @param port destination port + * @param rxstr generated regex, must be at least #GNUNET_TUN_IPV6_REGEXLEN + * bytes long. + */ +void +GNUNET_TUN_ipv6toregexsearch (const struct in6_addr *ipv6, + uint16_t port, + char *rxstr); + + +/** + * Convert an exit policy to a regular expression. The exit policy + * specifies a set of subnets this peer is willing to serve as an + * exit for; the resulting regular expression will match the + * IPv6 address strings as returned by #GNUNET_TUN_ipv6toregexsearch. + * + * @param policy exit policy specification + * @return regular expression, NULL on error + */ +char * +GNUNET_TUN_ipv6policy2regex (const char *policy); + + +/** + * Convert an exit policy to a regular expression. The exit policy + * specifies a set of subnets this peer is willing to serve as an + * exit for; the resulting regular expression will match the + * IPv4 address strings as returned by #GNUNET_TUN_ipv4toregexsearch. + * + * @param policy exit policy specification + * @return regular expression, NULL on error + */ +char * +GNUNET_TUN_ipv4policy2regex (const char *policy); + + +/** + * Hash the service name of a hosted service to the + * hash code that is used to identify the service on + * the network. + * + * @param service_name a string + * @param[out] hc corresponding hash + */ +void +GNUNET_TUN_service_name_to_hash (const char *service_name, + struct GNUNET_HashCode *hc); + + +/** + * Check if two sockaddrs are equal. + * + * @param sa one address + * @param sb another address + * @param include_port also check ports + * @return #GNUNET_YES if they are equal + */ +int +GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa, + const struct sockaddr *sb, + int include_port); + + +/** + * Compute the CADET port given a service descriptor + * (returned from #GNUNET_TUN_service_name_to_hash) and + * a TCP/UDP port @a ip_port. + * + * @param desc service shared secret + * @param ip_port TCP/UDP port, use 0 for ICMP + * @param[out] cadet_port CADET port to use + */ +void +GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc, + uint16_t ip_port, + struct GNUNET_HashCode *cadet_port); + +#endif + +/** @} */ /* end of group */ + +/** @} */ /* end of group addition */ diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_util_lib.h b/android_studio/distribution/libgnunet/lib/arm64-v8a/include/gnunet_util_lib.h @@ -0,0 +1,115 @@ +/* + This file is part of GNUnet + Copyright (C) 2009 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 + * Convenience header including all headers of subsystems in the gnunet_util library + * + * @see [Documentation](https://gnunet.org/libgnuneutil) + */ + +#ifndef GNUNET_UTIL_LIB_H +#define GNUNET_UTIL_LIB_H + +#define __GNUNET_UTIL_LIB_H_INSIDE__ + +#include <sys/socket.h> + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * Largest supported message (to be precise, one byte more + * than the largest possible message, so tests involving + * this value should check for messages being smaller than + * this value). + */ +#define GNUNET_MAX_MESSAGE_SIZE 65536 + +/** + * Smallest supported message. + */ +#define GNUNET_MIN_MESSAGE_SIZE sizeof(struct GNUNET_MessageHeader) + +/** + * NOTE: You MUST adjust this URL to point to the location of a + * publicly accessible repository (or TGZ) containing the sources of + * THIS release. Otherwise, you are violating the Affero GPL if you make + * this service available to anyone but yourself. + */ +#define GNUNET_AGPL_URL "https://git.gnunet.org/gnunet.git/tag/?h=v" \ + GNUNET_VERSION + +#include "gnunet_config.h" +#include "gnunet_common.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_bandwidth_lib.h" +#include "gnunet_bio_lib.h" +#include "gnunet_buffer_lib.h" +#include "gnunet_client_lib.h" +#include "gnunet_container_lib.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_helper_lib.h" +#include "gnunet_mst_lib.h" +#include "gnunet_mq_lib.h" +#include "gnunet_nt_lib.h" +#include "gnunet_nc_lib.h" +#include "gnunet_os_lib.h" +#include "gnunet_peer_lib.h" +#include "gnunet_plugin_lib.h" +#include "gnunet_program_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_service_lib.h" +#include "gnunet_signal_lib.h" +#include "gnunet_strings_lib.h" +#include "gnunet_tun_lib.h" +#include "gnunet_dnsstub_lib.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_child_management_lib.h" +#include "gnunet_error_codes.h" + + +/** + * Stringify operator. + * + * @param a some expression to stringify. Must NOT be a macro. + * @return same expression as a constant string. + */ +#define GNUNET_S(a) #a + + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#undef __GNUNET_UTIL_LIB_H_INSIDE__ + +#endif diff --git a/android_studio/distribution/libgnunet/lib/arm64-v8a/libgnunet.so b/android_studio/distribution/libgnunet/lib/arm64-v8a/libgnunet.so Binary files differ. diff --git a/android_studio/distribution/libgnunetarm/lib/arm64-v8a/libgnunetarm.so b/android_studio/distribution/libgnunetarm/lib/arm64-v8a/libgnunetarm.so Binary files differ. diff --git a/android_studio/distribution/libgnunethello/lib/arm64-v8a/libgnunethello.so b/android_studio/distribution/libgnunethello/lib/arm64-v8a/libgnunethello.so Binary files differ. diff --git a/android_studio/distribution/libgnunetpeerstore/lib/arm64-v8a/libgnunetpeerstore.so b/android_studio/distribution/libgnunetpeerstore/lib/arm64-v8a/libgnunetpeerstore.so Binary files differ. diff --git a/android_studio/distribution/libgnunetsq/lib/arm64-v8a/libgnunetsq.so b/android_studio/distribution/libgnunetsq/lib/arm64-v8a/libgnunetsq.so Binary files differ. diff --git a/android_studio/distribution/libgnunetstatistics/lib/arm64-v8a/libgnunetstatistics.so b/android_studio/distribution/libgnunetstatistics/lib/arm64-v8a/libgnunetstatistics.so Binary files differ. diff --git a/android_studio/distribution/libgnunettransportapplication/lib/arm64-v8a/libgnunettransportapplication.so b/android_studio/distribution/libgnunettransportapplication/lib/arm64-v8a/libgnunettransportapplication.so Binary files differ. diff --git a/android_studio/distribution/libgnunettransportcommunicator/lib/arm64-v8a/libgnunettransportcommunicator.so b/android_studio/distribution/libgnunettransportcommunicator/lib/arm64-v8a/libgnunettransportcommunicator.so Binary files differ. diff --git a/android_studio/distribution/libgnunettransportcore/lib/arm64-v8a/libgnunettransportcore.so b/android_studio/distribution/libgnunettransportcore/lib/arm64-v8a/libgnunettransportcore.so Binary files differ. diff --git a/android_studio/distribution/libgnunettransportmonitor/lib/arm64-v8a/libgnunettransportmonitor.so b/android_studio/distribution/libgnunettransportmonitor/lib/arm64-v8a/libgnunettransportmonitor.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/distribution/libidn/lib/arm64-v8a/include/idn-int.h b/android_studio/distribution/libidn/lib/arm64-v8a/include/idn-int.h @@ -0,0 +1,743 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +/* Copyright (C) 2001-2002, 2004-2024 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. + This file is part of gnulib. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +/* + * ISO C 99 <stdint.h> for platforms that lack it. + * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.html> + */ + +#ifndef _GL_LGL_STDINT_H + +#if __GNUC__ >= 3 +#pragma GCC system_header +#endif + + +/* When including a system file that in turn includes <inttypes.h>, + use the system <inttypes.h>, not our substitute. This avoids + problems with (for example) VMS, whose <sys/bitypes.h> includes + <inttypes.h>. */ +#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* On Android (Bionic libc), <sys/types.h> includes this file before + having defined 'time_t'. Therefore in this case avoid including + other system header files; just include the system's <stdint.h>. + Ideally we should test __BIONIC__ here, but it is only defined after + <sys/cdefs.h> has been included; hence test __ANDROID__ instead. */ +#if defined __ANDROID__ && defined _GL_INCLUDING_SYS_TYPES_H +# include <stdint.h> +#else + +/* Get those types that are already defined in other system include + files, so that we can "#define int8_t signed char" below without + worrying about a later system include file containing a "typedef + signed char int8_t;" that will get messed up by our macro. Our + macros should all be consistent with the system versions, except + for the "fast" types and macros, which we recommend against using + in public interfaces due to compiler differences. */ + +#if 1 +# if defined __sgi && ! defined __c99 + /* Bypass IRIX's <stdint.h> if in C89 mode, since it merely annoys users + with "This header file is to be used only for c99 mode compilations" + diagnostics. */ +# define __STDINT_H__ +# endif + + /* Some pre-C++11 <stdint.h> implementations need this. */ +# ifdef __cplusplus +# ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS 1 +# endif +# ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS 1 +# endif +# endif + + /* Other systems may have an incomplete or buggy <stdint.h>. + Include it before <inttypes.h>, since any "#include <stdint.h>" + in <inttypes.h> would reinclude us, skipping our contents because + _GL_LGL_STDINT_H is defined. + The include requires a split double-inclusion guard. */ +# include <stdint.h> +#endif + +#if ! defined _GL_LGL_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H +#define _GL_LGL_STDINT_H + +/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, + LONG_MIN, LONG_MAX, ULONG_MAX, _GL_INTEGER_WIDTH. */ +#include <limits.h> + +/* Override WINT_MIN and WINT_MAX if gnulib's <wchar.h> or <wctype.h> overrides + wint_t. */ +#if 0 +# undef WINT_MIN +# undef WINT_MAX +# define WINT_MIN 0x0U +# define WINT_MAX 0xffffffffU +#endif + +#if ! 0 + +/* <sys/types.h> defines some of the stdint.h types as well, on glibc, + IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>). + AIX 5.2 <sys/types.h> isn't needed and causes troubles. + Mac OS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but + relies on the system <stdint.h> definitions, so include + <sys/types.h> after <stdint.h>. */ +# if 1 && ! defined _AIX +# include <sys/types.h> +# endif + +# if 1 + /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines + int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. + <inttypes.h> also defines intptr_t and uintptr_t. */ +# include <inttypes.h> +# elif 0 + /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and + the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ +# include <sys/inttypes.h> +# endif + +# if 0 && ! defined __BIT_TYPES_DEFINED__ + /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines + int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is + included by <sys/types.h>. */ +# include <sys/bitypes.h> +# endif + +# undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* Minimum and maximum values for an integer type under the usual assumption. + Return an unspecified value if BITS == 0, adding a check to pacify + picky compilers. */ + +/* These are separate macros, because if you try to merge these macros into + a single one, HP-UX cc rejects the resulting expression in constant + expressions. */ +# define _STDINT_UNSIGNED_MIN(bits, zero) \ + (zero) +# define _STDINT_SIGNED_MIN(bits, zero) \ + (~ _STDINT_MAX (1, bits, zero)) + +# define _STDINT_MAX(signed, bits, zero) \ + (((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) + +#if !GNULIB_defined_stdint_types + +/* 7.18.1.1. Exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +# undef int8_t +# undef uint8_t +typedef signed char gl_int8_t; +typedef unsigned char gl_uint8_t; +# define int8_t gl_int8_t +# define uint8_t gl_uint8_t + +# undef int16_t +# undef uint16_t +typedef short int gl_int16_t; +typedef unsigned short int gl_uint16_t; +# define int16_t gl_int16_t +# define uint16_t gl_uint16_t + +# undef int32_t +# undef uint32_t +typedef int gl_int32_t; +typedef unsigned int gl_uint32_t; +# define int32_t gl_int32_t +# define uint32_t gl_uint32_t + +/* If the system defines INT64_MAX, assume int64_t works. That way, + if the underlying platform defines int64_t to be a 64-bit long long + int, the code below won't mistakenly define it to be a 64-bit long + int, which would mess up C++ name mangling. We must use #ifdef + rather than #if, to avoid an error with HP-UX 10.20 cc. */ + +# ifdef INT64_MAX +# define GL_INT64_T +# else +/* Do not undefine int64_t if gnulib is not being used with 64-bit + types, since otherwise it breaks platforms like Tandem/NSK. */ +# if LONG_MAX >> 31 >> 31 == 1 +# undef int64_t +typedef long int gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +# elif defined _MSC_VER +# undef int64_t +typedef __int64 gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +# else +# undef int64_t +typedef long long int gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +# endif +# endif + +# ifdef UINT64_MAX +# define GL_UINT64_T +# else +# if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# undef uint64_t +typedef unsigned long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +# elif defined _MSC_VER +# undef uint64_t +typedef unsigned __int64 gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +# else +# undef uint64_t +typedef unsigned long long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +# endif +# endif + +/* Avoid collision with Solaris 2.5.1 <pthread.h> etc. */ +# define _UINT8_T +# define _UINT32_T +# define _UINT64_T + + +/* 7.18.1.2. Minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +# undef int_least8_t +# undef uint_least8_t +# undef int_least16_t +# undef uint_least16_t +# undef int_least32_t +# undef uint_least32_t +# undef int_least64_t +# undef uint_least64_t +# define int_least8_t int8_t +# define uint_least8_t uint8_t +# define int_least16_t int16_t +# define uint_least16_t uint16_t +# define int_least32_t int32_t +# define uint_least32_t uint32_t +# ifdef GL_INT64_T +# define int_least64_t int64_t +# endif +# ifdef GL_UINT64_T +# define uint_least64_t uint64_t +# endif + +/* 7.18.1.3. Fastest minimum-width integer types */ + +/* Note: Other <stdint.h> substitutes may define these types differently. + It is not recommended to use these types in public header files. */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. The following code normally + uses types consistent with glibc, as that lessens the chance of + incompatibility with older GNU hosts. */ + +# undef int_fast8_t +# undef uint_fast8_t +# undef int_fast16_t +# undef uint_fast16_t +# undef int_fast32_t +# undef uint_fast32_t +# undef int_fast64_t +# undef uint_fast64_t +typedef signed char gl_int_fast8_t; +typedef unsigned char gl_uint_fast8_t; + +# ifdef __sun +/* Define types compatible with SunOS 5.10, so that code compiled under + earlier SunOS versions works with code compiled under SunOS 5.10. */ +typedef int gl_int_fast32_t; +typedef unsigned int gl_uint_fast32_t; +# else +typedef long int gl_int_fast32_t; +typedef unsigned long int gl_uint_fast32_t; +# endif +typedef gl_int_fast32_t gl_int_fast16_t; +typedef gl_uint_fast32_t gl_uint_fast16_t; + +# define int_fast8_t gl_int_fast8_t +# define uint_fast8_t gl_uint_fast8_t +# define int_fast16_t gl_int_fast16_t +# define uint_fast16_t gl_uint_fast16_t +# define int_fast32_t gl_int_fast32_t +# define uint_fast32_t gl_uint_fast32_t +# ifdef GL_INT64_T +# define int_fast64_t int64_t +# endif +# ifdef GL_UINT64_T +# define uint_fast64_t uint64_t +# endif + +/* 7.18.1.4. Integer types capable of holding object pointers */ + +/* kLIBC's <stdint.h> defines _INTPTR_T_DECLARED and needs its own + definitions of intptr_t and uintptr_t (which use int and unsigned) + to avoid clashes with declarations of system functions like sbrk. + Similarly, MinGW WSL-5.4.1 <stdint.h> needs its own intptr_t and + uintptr_t to avoid conflicting declarations of system functions like + _findclose in <io.h>. */ +# if !((defined __KLIBC__ && defined _INTPTR_T_DECLARED) \ + || (defined __INTPTR_WIDTH__ \ + && __INTPTR_WIDTH__ != (defined _WIN64 ? LLONG_WIDTH : LONG_WIDTH)) \ + || defined __MINGW32__) +# undef intptr_t +# undef uintptr_t +# ifdef _WIN64 +typedef long long int gl_intptr_t; +typedef unsigned long long int gl_uintptr_t; +# else +typedef long int gl_intptr_t; +typedef unsigned long int gl_uintptr_t; +# endif +# define intptr_t gl_intptr_t +# define uintptr_t gl_uintptr_t +# endif + +/* 7.18.1.5. Greatest-width integer types */ + +/* Note: These types are compiler dependent. It may be unwise to use them in + public header files. */ + +/* If the system defines INTMAX_MAX, assume that intmax_t works, and + similarly for UINTMAX_MAX and uintmax_t. This avoids problems with + assuming one type where another is used by the system. */ + +# ifndef INTMAX_MAX +# undef INTMAX_C +# undef intmax_t +# if LONG_MAX >> 30 == 1 +typedef long long int gl_intmax_t; +# define intmax_t gl_intmax_t +# elif defined GL_INT64_T +# define intmax_t int64_t +# else +typedef long int gl_intmax_t; +# define intmax_t gl_intmax_t +# endif +# endif + +# ifndef UINTMAX_MAX +# undef UINTMAX_C +# undef uintmax_t +# if ULONG_MAX >> 31 == 1 +typedef unsigned long long int gl_uintmax_t; +# define uintmax_t gl_uintmax_t +# elif defined GL_UINT64_T +# define uintmax_t uint64_t +# else +typedef unsigned long int gl_uintmax_t; +# define uintmax_t gl_uintmax_t +# endif +# endif + +/* Verify that intmax_t and uintmax_t have the same size. Too much code + breaks if this is not the case. If this check fails, the reason is likely + to be found in the autoconf macros. */ +typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) + ? 1 : -1]; + +# define GNULIB_defined_stdint_types 1 +# endif /* !GNULIB_defined_stdint_types */ + +/* 7.18.2. Limits of specified-width integer types */ + +/* 7.18.2.1. Limits of exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +# undef INT8_MIN +# undef INT8_MAX +# undef UINT8_MAX +# define INT8_MIN (~ INT8_MAX) +# define INT8_MAX 127 +# define UINT8_MAX 255 + +# undef INT16_MIN +# undef INT16_MAX +# undef UINT16_MAX +# define INT16_MIN (~ INT16_MAX) +# define INT16_MAX 32767 +# define UINT16_MAX 65535 + +# undef INT32_MIN +# undef INT32_MAX +# undef UINT32_MAX +# define INT32_MIN (~ INT32_MAX) +# define INT32_MAX 2147483647 +# define UINT32_MAX 4294967295U + +# if defined GL_INT64_T && ! defined INT64_MAX +/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 + evaluates the latter incorrectly in preprocessor expressions. */ +# define INT64_MIN (- INTMAX_C (1) << 63) +# define INT64_MAX INTMAX_C (9223372036854775807) +# endif + +# if defined GL_UINT64_T && ! defined UINT64_MAX +# define UINT64_MAX UINTMAX_C (18446744073709551615) +# endif + +/* 7.18.2.2. Limits of minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +# undef INT_LEAST8_MIN +# undef INT_LEAST8_MAX +# undef UINT_LEAST8_MAX +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST8_MAX INT8_MAX +# define UINT_LEAST8_MAX UINT8_MAX + +# undef INT_LEAST16_MIN +# undef INT_LEAST16_MAX +# undef UINT_LEAST16_MAX +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST16_MAX INT16_MAX +# define UINT_LEAST16_MAX UINT16_MAX + +# undef INT_LEAST32_MIN +# undef INT_LEAST32_MAX +# undef UINT_LEAST32_MAX +# define INT_LEAST32_MIN INT32_MIN +# define INT_LEAST32_MAX INT32_MAX +# define UINT_LEAST32_MAX UINT32_MAX + +# undef INT_LEAST64_MIN +# undef INT_LEAST64_MAX +# ifdef GL_INT64_T +# define INT_LEAST64_MIN INT64_MIN +# define INT_LEAST64_MAX INT64_MAX +# endif + +# undef UINT_LEAST64_MAX +# ifdef GL_UINT64_T +# define UINT_LEAST64_MAX UINT64_MAX +# endif + +/* 7.18.2.3. Limits of fastest minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. */ + +# undef INT_FAST8_MIN +# undef INT_FAST8_MAX +# undef UINT_FAST8_MAX +# define INT_FAST8_MIN SCHAR_MIN +# define INT_FAST8_MAX SCHAR_MAX +# define UINT_FAST8_MAX UCHAR_MAX + +# undef INT_FAST16_MIN +# undef INT_FAST16_MAX +# undef UINT_FAST16_MAX +# define INT_FAST16_MIN INT_FAST32_MIN +# define INT_FAST16_MAX INT_FAST32_MAX +# define UINT_FAST16_MAX UINT_FAST32_MAX + +# undef INT_FAST32_MIN +# undef INT_FAST32_MAX +# undef UINT_FAST32_MAX +# ifdef __sun +# define INT_FAST32_MIN INT_MIN +# define INT_FAST32_MAX INT_MAX +# define UINT_FAST32_MAX UINT_MAX +# else +# define INT_FAST32_MIN LONG_MIN +# define INT_FAST32_MAX LONG_MAX +# define UINT_FAST32_MAX ULONG_MAX +# endif + +# undef INT_FAST64_MIN +# undef INT_FAST64_MAX +# ifdef GL_INT64_T +# define INT_FAST64_MIN INT64_MIN +# define INT_FAST64_MAX INT64_MAX +# endif + +# undef UINT_FAST64_MAX +# ifdef GL_UINT64_T +# define UINT_FAST64_MAX UINT64_MAX +# endif + +/* 7.18.2.4. Limits of integer types capable of holding object pointers */ + +# undef INTPTR_MIN +# undef INTPTR_MAX +# undef UINTPTR_MAX +# ifdef _WIN64 +# define INTPTR_MIN LLONG_MIN +# define INTPTR_MAX LLONG_MAX +# define UINTPTR_MAX ULLONG_MAX +# else +# define INTPTR_MIN LONG_MIN +# define INTPTR_MAX LONG_MAX +# define UINTPTR_MAX ULONG_MAX +# endif + +/* 7.18.2.5. Limits of greatest-width integer types */ + +# ifndef INTMAX_MAX +# undef INTMAX_MIN +# ifdef INT64_MAX +# define INTMAX_MIN INT64_MIN +# define INTMAX_MAX INT64_MAX +# else +# define INTMAX_MIN INT32_MIN +# define INTMAX_MAX INT32_MAX +# endif +# endif + +# ifndef UINTMAX_MAX +# ifdef UINT64_MAX +# define UINTMAX_MAX UINT64_MAX +# else +# define UINTMAX_MAX UINT32_MAX +# endif +# endif + +/* 7.18.3. Limits of other integer types */ + +/* ptrdiff_t limits */ +# undef PTRDIFF_MIN +# undef PTRDIFF_MAX +# if 0 +# ifdef _LP64 +# define PTRDIFF_MIN _STDINT_SIGNED_MIN (64, 0l) +# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) +# else +# define PTRDIFF_MIN _STDINT_SIGNED_MIN (32, 0) +# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) +# endif +# else +# define PTRDIFF_MIN \ + _STDINT_SIGNED_MIN (64, 0l) +# define PTRDIFF_MAX \ + _STDINT_MAX (1, 64, 0l) +# endif + +/* sig_atomic_t limits */ +# undef SIG_ATOMIC_MIN +# undef SIG_ATOMIC_MAX +# if 1 +# define SIG_ATOMIC_MIN \ + _STDINT_SIGNED_MIN (32, 0) +# else +# define SIG_ATOMIC_MIN \ + _STDINT_UNSIGNED_MIN (32, 0) +# endif +# define SIG_ATOMIC_MAX \ + _STDINT_MAX (1, 32, \ + 0) + + +/* size_t limit */ +# undef SIZE_MAX +# if 0 +# ifdef _LP64 +# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +# else +# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# endif +# else +# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +# endif + +/* wchar_t limits */ +/* Get WCHAR_MIN, WCHAR_MAX. + This include is not on the top, above, because on OSF/1 4.0 we have a + sequence of nested includes + <wchar.h> -> <stdio.h> -> <getopt.h> -> <stdlib.h>, and the latter includes + <stdint.h> and assumes its types are already defined. */ +# if 1 && ! (defined WCHAR_MIN && defined WCHAR_MAX) +# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +# include <wchar.h> +# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +# endif +# undef WCHAR_MIN +# undef WCHAR_MAX +# if 0 +# define WCHAR_MIN \ + _STDINT_SIGNED_MIN (32, 0u) +# else +# define WCHAR_MIN \ + _STDINT_UNSIGNED_MIN (32, 0u) +# endif +# define WCHAR_MAX \ + _STDINT_MAX (0, 32, 0u) + +/* wint_t limits */ +/* If gnulib's <wchar.h> or <wctype.h> overrides wint_t, u is not + accurate, therefore use the definitions from above. */ +# if !0 +# undef WINT_MIN +# undef WINT_MAX +# if 0 +# define WINT_MIN \ + _STDINT_SIGNED_MIN (32, 0u) +# else +# define WINT_MIN \ + _STDINT_UNSIGNED_MIN (32, 0u) +# endif +# define WINT_MAX \ + _STDINT_MAX (0, 32, 0u) +# endif + +/* 7.18.4. Macros for integer constants */ + +/* 7.18.4.1. Macros for minimum-width integer constants */ +/* According to ISO C 99 Technical Corrigendum 1 */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ + +# undef INT8_C +# undef UINT8_C +# define INT8_C(x) x +# define UINT8_C(x) x + +# undef INT16_C +# undef UINT16_C +# define INT16_C(x) x +# define UINT16_C(x) x + +# undef INT32_C +# undef UINT32_C +# define INT32_C(x) x +# define UINT32_C(x) x ## U + +# undef INT64_C +# undef UINT64_C +# if LONG_MAX >> 31 >> 31 == 1 +# define INT64_C(x) x##L +# elif defined _MSC_VER +# define INT64_C(x) x##i64 +# else +# define INT64_C(x) x##LL +# endif +# if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# define UINT64_C(x) x##UL +# elif defined _MSC_VER +# define UINT64_C(x) x##ui64 +# else +# define UINT64_C(x) x##ULL +# endif + +/* 7.18.4.2. Macros for greatest-width integer constants */ + +# ifndef INTMAX_C +# if LONG_MAX >> 30 == 1 +# define INTMAX_C(x) x##LL +# elif defined GL_INT64_T +# define INTMAX_C(x) INT64_C(x) +# else +# define INTMAX_C(x) x##L +# endif +# endif + +# ifndef UINTMAX_C +# if ULONG_MAX >> 31 == 1 +# define UINTMAX_C(x) x##ULL +# elif defined GL_UINT64_T +# define UINTMAX_C(x) UINT64_C(x) +# else +# define UINTMAX_C(x) x##UL +# endif +# endif + +#endif /* !0 */ + +/* Macros specified by ISO/IEC TS 18661-1:2014. */ + +#if (!defined UINTMAX_WIDTH \ + && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__)) +# ifdef INT8_MAX +# define INT8_WIDTH _GL_INTEGER_WIDTH (INT8_MIN, INT8_MAX) +# endif +# ifdef UINT8_MAX +# define UINT8_WIDTH _GL_INTEGER_WIDTH (0, UINT8_MAX) +# endif +# ifdef INT16_MAX +# define INT16_WIDTH _GL_INTEGER_WIDTH (INT16_MIN, INT16_MAX) +# endif +# ifdef UINT16_MAX +# define UINT16_WIDTH _GL_INTEGER_WIDTH (0, UINT16_MAX) +# endif +# ifdef INT32_MAX +# define INT32_WIDTH _GL_INTEGER_WIDTH (INT32_MIN, INT32_MAX) +# endif +# ifdef UINT32_MAX +# define UINT32_WIDTH _GL_INTEGER_WIDTH (0, UINT32_MAX) +# endif +# ifdef INT64_MAX +# define INT64_WIDTH _GL_INTEGER_WIDTH (INT64_MIN, INT64_MAX) +# endif +# ifdef UINT64_MAX +# define UINT64_WIDTH _GL_INTEGER_WIDTH (0, UINT64_MAX) +# endif +# define INT_LEAST8_WIDTH _GL_INTEGER_WIDTH (INT_LEAST8_MIN, INT_LEAST8_MAX) +# define UINT_LEAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST8_MAX) +# define INT_LEAST16_WIDTH _GL_INTEGER_WIDTH (INT_LEAST16_MIN, INT_LEAST16_MAX) +# define UINT_LEAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST16_MAX) +# define INT_LEAST32_WIDTH _GL_INTEGER_WIDTH (INT_LEAST32_MIN, INT_LEAST32_MAX) +# define UINT_LEAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST32_MAX) +# define INT_LEAST64_WIDTH _GL_INTEGER_WIDTH (INT_LEAST64_MIN, INT_LEAST64_MAX) +# define UINT_LEAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST64_MAX) +# define INT_FAST8_WIDTH _GL_INTEGER_WIDTH (INT_FAST8_MIN, INT_FAST8_MAX) +# define UINT_FAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST8_MAX) +# define INT_FAST16_WIDTH _GL_INTEGER_WIDTH (INT_FAST16_MIN, INT_FAST16_MAX) +# define UINT_FAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST16_MAX) +# define INT_FAST32_WIDTH _GL_INTEGER_WIDTH (INT_FAST32_MIN, INT_FAST32_MAX) +# define UINT_FAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST32_MAX) +# define INT_FAST64_WIDTH _GL_INTEGER_WIDTH (INT_FAST64_MIN, INT_FAST64_MAX) +# define UINT_FAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST64_MAX) +# define INTPTR_WIDTH _GL_INTEGER_WIDTH (INTPTR_MIN, INTPTR_MAX) +# define UINTPTR_WIDTH _GL_INTEGER_WIDTH (0, UINTPTR_MAX) +# define INTMAX_WIDTH _GL_INTEGER_WIDTH (INTMAX_MIN, INTMAX_MAX) +# define UINTMAX_WIDTH _GL_INTEGER_WIDTH (0, UINTMAX_MAX) +# define PTRDIFF_WIDTH _GL_INTEGER_WIDTH (PTRDIFF_MIN, PTRDIFF_MAX) +# define SIZE_WIDTH _GL_INTEGER_WIDTH (0, SIZE_MAX) +# define WCHAR_WIDTH _GL_INTEGER_WIDTH (WCHAR_MIN, WCHAR_MAX) +# ifdef WINT_MAX +# define WINT_WIDTH _GL_INTEGER_WIDTH (WINT_MIN, WINT_MAX) +# endif +# ifdef SIG_ATOMIC_MAX +# define SIG_ATOMIC_WIDTH _GL_INTEGER_WIDTH (SIG_ATOMIC_MIN, SIG_ATOMIC_MAX) +# endif +#endif /* !WINT_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */ + +#endif /* _GL_LGL_STDINT_H */ +#endif /* !(defined __ANDROID__ && ...) */ +#endif /* !defined _GL_LGL_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ diff --git a/android_studio/distribution/libidn/lib/arm64-v8a/include/idna.h b/android_studio/distribution/libidn/lib/arm64-v8a/include/idna.h @@ -0,0 +1,141 @@ +/* idna.h --- Prototypes for Internationalized Domain Name library. + Copyright (C) 2002-2024 Simon Josefsson + + This file is part of GNU Libidn. + + GNU Libidn is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version. + + or both in parallel, as here. + + GNU Libidn 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 + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see <https://www.gnu.org/licenses/>. */ + +#ifndef IDNA_H +# define IDNA_H + +/** + * SECTION:idna + * @title: idna.h + * @short_description: IDNA-related functions + * + * IDNA-related functions. + */ + +/** + * IDNAPI: + * + * Symbol holding shared library API visibility decorator. + * + * This is used internally by the library header file and should never + * be used or modified by the application. + * + * https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html + */ +# ifndef IDNAPI +# if defined LIBIDN_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY +# define IDNAPI __attribute__((__visibility__("default"))) +# elif defined LIBIDN_BUILDING && defined _MSC_VER && ! defined LIBIDN_STATIC +# define IDNAPI __declspec(dllexport) +# elif defined _MSC_VER && ! defined LIBIDN_STATIC +# define IDNAPI __declspec(dllimport) +# else +# define IDNAPI +# endif +# endif + +# include <stddef.h> /* size_t */ +# include <idn-int.h> /* uint32_t */ + +# ifdef __cplusplus +extern "C" +{ +# endif + + /* Error codes. */ + typedef enum + { + IDNA_SUCCESS = 0, + IDNA_STRINGPREP_ERROR = 1, + IDNA_PUNYCODE_ERROR = 2, + IDNA_CONTAINS_NON_LDH = 3, + /* Workaround typo in earlier versions. */ + IDNA_CONTAINS_LDH = IDNA_CONTAINS_NON_LDH, + IDNA_CONTAINS_MINUS = 4, + IDNA_INVALID_LENGTH = 5, + IDNA_NO_ACE_PREFIX = 6, + IDNA_ROUNDTRIP_VERIFY_ERROR = 7, + IDNA_CONTAINS_ACE_PREFIX = 8, + IDNA_ICONV_ERROR = 9, + /* Internal errors. */ + IDNA_MALLOC_ERROR = 201, + IDNA_DLOPEN_ERROR = 202 + } Idna_rc; + + /* IDNA flags */ + typedef enum + { + IDNA_ALLOW_UNASSIGNED = 0x0001, + IDNA_USE_STD3_ASCII_RULES = 0x0002 + } Idna_flags; + +# ifndef IDNA_ACE_PREFIX +# define IDNA_ACE_PREFIX "xn--" +# endif + + extern IDNAPI const char *idna_strerror (Idna_rc rc); + + /* Core functions */ + extern IDNAPI int idna_to_ascii_4i (const uint32_t * in, size_t inlen, + char *out, int flags); + extern IDNAPI int idna_to_unicode_44i (const uint32_t * in, size_t inlen, + uint32_t * out, size_t *outlen, + int flags); + + /* Wrappers that handle several labels */ + + extern IDNAPI int idna_to_ascii_4z (const uint32_t * input, + char **output, int flags); + + extern IDNAPI int idna_to_ascii_8z (const char *input, char **output, + int flags); + + extern IDNAPI int idna_to_ascii_lz (const char *input, char **output, + int flags); + + extern IDNAPI int idna_to_unicode_4z4z (const uint32_t * input, + uint32_t ** output, int flags); + + extern IDNAPI int idna_to_unicode_8z4z (const char *input, + uint32_t ** output, int flags); + + extern IDNAPI int idna_to_unicode_8z8z (const char *input, + char **output, int flags); + + extern IDNAPI int idna_to_unicode_8zlz (const char *input, + char **output, int flags); + + extern IDNAPI int idna_to_unicode_lzlz (const char *input, + char **output, int flags); + +# ifdef __cplusplus +} +# endif + +#endif /* IDNA_H */ diff --git a/android_studio/distribution/libidn/lib/arm64-v8a/libidn.so b/android_studio/distribution/libidn/lib/arm64-v8a/libidn.so Binary files differ.