[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r32181 - in gnunet-java: . bin src/main/java/org/gnunet/con
From: |
gnunet |
Subject: |
[GNUnet-SVN] r32181 - in gnunet-java: . bin src/main/java/org/gnunet/consensus src/main/java/org/gnunet/consensus/messages src/main/java/org/gnunet/construct src/main/java/org/gnunet/core src/main/java/org/gnunet/gns src/main/java/org/gnunet/gns/messages src/main/java/org/gnunet/identity src/main/java/org/gnunet/peerinfo src/main/java/org/gnunet/testing src/main/java/org/gnunet/transport src/main/java/org/gnunet/transport/messages src/main/java/org/gnunet/util src/main/java/org/gnunet/util/crypto src/main/java/org/gnunet/voting src/main/resources/org/gnunet/construct src/test/java/org/gnunet/consensus src/test/java/org/gnunet/core src/test/java/org/gnunet/identity src/test/java/org/gnunet/transport src/test/java/org/gnunet/util |
Date: |
Tue, 4 Feb 2014 00:03:52 +0100 |
Author: dold
Date: 2014-02-04 00:03:52 +0100 (Tue, 04 Feb 2014)
New Revision: 32181
Added:
gnunet-java/bin/gnunet-gns
Modified:
gnunet-java/ISSUES
gnunet-java/build.gradle
gnunet-java/src/main/java/org/gnunet/consensus/Consensus.java
gnunet-java/src/main/java/org/gnunet/consensus/messages/ConcludeMessage.java
gnunet-java/src/main/java/org/gnunet/consensus/messages/JoinMessage.java
gnunet-java/src/main/java/org/gnunet/construct/MessageLoader.java
gnunet-java/src/main/java/org/gnunet/core/Core.java
gnunet-java/src/main/java/org/gnunet/core/SendMessage.java
gnunet-java/src/main/java/org/gnunet/gns/GnsRecord.java
gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupMessage.java
gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupResultMessage.java
gnunet-java/src/main/java/org/gnunet/identity/Identity.java
gnunet-java/src/main/java/org/gnunet/peerinfo/PeerInfo.java
gnunet-java/src/main/java/org/gnunet/testing/TestingFixture.java
gnunet-java/src/main/java/org/gnunet/transport/Transport.java
gnunet-java/src/main/java/org/gnunet/transport/messages/StartMessage.java
gnunet-java/src/main/java/org/gnunet/util/Connection.java
gnunet-java/src/main/java/org/gnunet/util/MessageStreamTokenizer.java
gnunet-java/src/main/java/org/gnunet/util/PeerIdentity.java
gnunet-java/src/main/java/org/gnunet/util/RelativeTime.java
gnunet-java/src/main/java/org/gnunet/util/Scheduler.java
gnunet-java/src/main/java/org/gnunet/util/crypto/DsaPrng.java
gnunet-java/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java
gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java
gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java
gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java
gnunet-java/src/main/java/org/gnunet/util/crypto/Ed25519.java
gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java
gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaSignature.java
gnunet-java/src/main/java/org/gnunet/voting/BallotTool.java
gnunet-java/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java
gnunet-java/src/main/resources/org/gnunet/construct/MsgMap.txt
gnunet-java/src/test/java/org/gnunet/consensus/ConsensusSingleTest.java
gnunet-java/src/test/java/org/gnunet/consensus/ConsensusTestbedTest.java
gnunet-java/src/test/java/org/gnunet/core/CoreTest.java
gnunet-java/src/test/java/org/gnunet/identity/IdentityTest.java
gnunet-java/src/test/java/org/gnunet/transport/TransportTest.java
gnunet-java/src/test/java/org/gnunet/util/ClientServerTest.java
gnunet-java/src/test/java/org/gnunet/util/EcdheTest.java
gnunet-java/src/test/java/org/gnunet/util/EcdsaTest.java
gnunet-java/src/test/java/org/gnunet/util/Ed25519Test.java
Log:
- scheduler-per-thread
- fixed ECDSA and crypto endianess
- Gns and GnsTool implemented
- updated consensus protocol
Modified: gnunet-java/ISSUES
===================================================================
--- gnunet-java/ISSUES 2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/ISSUES 2014-02-03 23:03:52 UTC (rev 32181)
@@ -1,51 +1,35 @@
-secretsharing
- * plaintexts:
- * due to the (sub-)group we chose, not every bit pattern is a valid
- message
- * => GNUNET_SECRETSHARING_message_generate (...)
+scheduler:
+ * scheduler-pre-thread implemented
-secretsharing working, both keygen and decryption
- * debugging was a pain ...
- * some mesh crashes appear randomly ...
+crypto:
+ * ECDSA now works correctly ... annoying to fix but entirely my fault
+ * => all the crypto is compatible now
-libgcrypt:
-The following code does not terminate.
+paillier:
+ * something broke paillier ... both cfuchs and me are not sure what ...
+ * had to bisect the repo ...
- gcry_mpi_set_ui (x, 0);
- gcry_mpi_sub_ui (x, x, 1);
- gcry_mpi_set_ui (p, 17);
- gcry_mpi_invm (x, x, p);
-
-... which was very "nice" to spot because
- gcry_mpi_dump prints -1 as "01" ...
-
- * it's kind of hard to trust any gcry_mpi_* op that involves
- any kind of negative value ....
-
- * it's not documented what powm does when the exponent is negative, but the
inverse
- does not exist!
- * invm at least returns an error flag ...
-
-
secretsharing:
- * problem with valgrind+testbed: slows stuff down, serialized due to testbed
- * consensi get out of sync, but are started at the very beginning
- * proposal: also specify start time for DKG,
- crypto setup is done *before* start time (of consensus)
+ * key generation works with 'many' (16) peers
+ * sometimes, consensus seems to hang ... still trying to find the cause
+ * very large groups would have problems with element size
+ * distributed key generation still fails sometimes ... seems to be a
+ problem with the crypto implementation
-paillier is now in util!
+GNS:
+ * is pin the new FCFS? Why does is not seem to work?
+ * see the two bugs reported (namestore deletion, PKEY+others hangup)
+ * GNS in java:
+ * record types are implemented as Construct unions
+ * org.gnunet.gns.records.Record is the message union
+ * @UnionCase specifies the record number
+ * records must have a static recordTypeName, recordTypeId
+ * ... which is put in a table with reflection
+ * createFromString("A", "127.0.0.1") uses reflection
+ * recData.getRecordString instead of recData.toString, as toString should
not return null
+ * => extensible via classpath
+ * gnunet-gns is also re-implemented in java now
-next: implement ZKPs
+Feb 02 19:23:20-300517 util-20283 DEBUG Connection transmitted 93/93 bytes to
`/run/user/1000/gnunet-dold-runtime//gnunet-service-g' (0xcc4250)
-
-GNS:
- * rudimentary implementation in gnunet-java
- * why is record type in gns_api int, and not unsigned int?
- * gnsrecord: we're lost in java with the plugins
- * call some helper bin for e.g. record type printing?
- * use JNA (ctypes-style library for Java)
- LookupMessage: string termination not documented
- * fixed, but can't we agree on one way?
- LookupResultMessage:
- /* followed by rd_count GNUNET_GNSRECORD_Data structs*/
- can't be true, as the struct contains a pointer ...
+The truncation is not very helpful
Added: gnunet-java/bin/gnunet-gns
===================================================================
--- gnunet-java/bin/gnunet-gns (rev 0)
+++ gnunet-java/bin/gnunet-gns 2014-02-03 23:03:52 UTC (rev 32181)
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if [ "%GNJ_INSTALLED" = "true" ];
+then
+ export CLASSPATH="%INSTALL_PATH/share/java/*"
+else
+ DIR=`dirname $0`
+ # if we are in the development environment use class files directly
instead of jar
+ export
CLASSPATH="$DIR/../build-gradle/classes/main/:$DIR/../build-gradle/resources/main/:$DIR/../lib/*"
+fi
+
+java -ea org.gnunet.gns.GnsTool "$@"
Property changes on: gnunet-java/bin/gnunet-gns
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: gnunet-java/build.gradle
===================================================================
--- gnunet-java/build.gradle 2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/build.gradle 2014-02-03 23:03:52 UTC (rev 32181)
@@ -4,16 +4,18 @@
apply plugin: 'java'
-buildDir = "$projectDir/build-gradle"
+buildDir = "$projectDir/build-gradle"
sourceCompatibility = "1.6"
targetCompatibility = "1.6"
// specify where to get jars
repositories {
+ // we either get them from the libs dir
flatDir {
dirs 'lib'
}
+ // or from the maven central repository
mavenCentral()
}
@@ -109,6 +111,8 @@
destinationDir = file("$buildDir/classes/main/")
}
+// Define task and dependencies for creating an IZPack installer.
+
project.ext.installerFile = "$projectDir/gnunet-java-installer.jar"
task installer (type: Exec) {
@@ -131,13 +135,17 @@
}
+// Which gradle version do we want to use
+// for the wrapper?
task wrapper(type: Wrapper) {
- gradleVersion = '1.7'
+ gradleVersion = '1.10'
}
-if (hasProperty("xlint")) {
- tasks.withType(Compile) {
- options.compilerArgs << "-Xlint:unchecked"
- }
+
+// Print test name, so that we can easily find out
+// which test does not terminate.
+test {
+ beforeTest{ descr ->
+ logger.warn("Starting Test ${descr.className} : ${descr.name}")
+ }
}
-
Modified: gnunet-java/src/main/java/org/gnunet/consensus/Consensus.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/consensus/Consensus.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/consensus/Consensus.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -69,6 +69,7 @@
@Override
public void handleError() {
+ System.out.println("Error receiving from consensus service.");
consensusCallback.onElement(null);
}
}
@@ -81,8 +82,11 @@
* Inclusion of the local peer is optional.
* @param sessionId session identifier
* Allows a group of peers to have more than consensus
session.
+ * @param startTime when should the consensus start?
+ * @param deadline when should we be done?
*/
- public Consensus(Configuration cfg, PeerIdentity[] peers, HashCode
sessionId) {
+ public Consensus(Configuration cfg, PeerIdentity[] peers, HashCode
sessionId,
+ AbsoluteTime startTime, AbsoluteTime deadline) {
client = new Client("consensus", cfg);
client.installReceiver(new ConsensusMessageReceiver());
@@ -90,6 +94,8 @@
m.numPeers = peers.length;
m.peers = peers;
m.sessionId = sessionId;
+ m.startTime = startTime.asMessage();
+ m.deadline = deadline.asMessage();
client.send(m);
}
@@ -131,16 +137,13 @@
* After conclude has been called, no further elements may be
* inserted by the client.
*
- * @param concludeTimeout timeout for conclude, may never be forever
* @param concludeCallback called when the consensus has concluded
*/
- public void conclude(RelativeTime concludeTimeout, ConsensusCallback
concludeCallback) {
+ public void conclude(ConsensusCallback concludeCallback) {
Preconditions.checkNotNull(concludeCallback, "conclude with null
callback");
Preconditions.checkState(null == this.consensusCallback, "called
conclude twice");
- Preconditions.checkArgument(!concludeTimeout.isForever(), "conclude
timeout may not be forever");
this.consensusCallback = concludeCallback;
ConcludeMessage m = new ConcludeMessage();
- m.concludeTimeout = concludeTimeout.toNetwork();
client.send(m);
}
Modified:
gnunet-java/src/main/java/org/gnunet/consensus/messages/ConcludeMessage.java
===================================================================
---
gnunet-java/src/main/java/org/gnunet/consensus/messages/ConcludeMessage.java
2014-02-03 23:00:30 UTC (rev 32180)
+++
gnunet-java/src/main/java/org/gnunet/consensus/messages/ConcludeMessage.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -21,10 +21,7 @@
package org.gnunet.consensus.messages;
import org.gnunet.construct.*;
-import org.gnunet.util.AbsoluteTime;
-import org.gnunet.util.GnunetMessage;
-import org.gnunet.util.RelativeTime;
-import org.gnunet.util.RelativeTimeMessage;
+import org.gnunet.util.*;
/**
* Notify the client of a new element.
@@ -35,6 +32,4 @@
*/
@UnionCase(524)
public class ConcludeMessage implements GnunetMessage.Body {
- @NestedMessage
- public RelativeTimeMessage concludeTimeout;
}
\ No newline at end of file
Modified:
gnunet-java/src/main/java/org/gnunet/consensus/messages/JoinMessage.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/consensus/messages/JoinMessage.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/consensus/messages/JoinMessage.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -24,6 +24,7 @@
import org.gnunet.construct.UInt32;
import org.gnunet.construct.UnionCase;
import org.gnunet.construct.VariableSizeArray;
+import org.gnunet.util.AbsoluteTimeMessage;
import org.gnunet.util.GnunetMessage;
import org.gnunet.util.HashCode;
import org.gnunet.util.PeerIdentity;
@@ -34,6 +35,9 @@
public int numPeers;
@NestedMessage
public HashCode sessionId;
+ @NestedMessage
+ public AbsoluteTimeMessage startTime;
+ public AbsoluteTimeMessage deadline;
@VariableSizeArray(lengthField = "numPeers")
public PeerIdentity[] peers;
}
Modified: gnunet-java/src/main/java/org/gnunet/construct/MessageLoader.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/construct/MessageLoader.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/construct/MessageLoader.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -197,6 +197,12 @@
return map.get(unionCase);
}
+ public static Class<? extends MessageUnion>[] getUnionCases(Class<?
extends MessageUnion> unionInterface) {
+ Map<Class<? extends MessageUnion>, Integer> map =
tagmap.get(unionInterface);
+ //noinspection unchecked
+ return (Class<? extends MessageUnion>[]) map.keySet().toArray(new
Class[map.keySet().size()]);
+ }
+
public static void registerUnionCase(Class<? extends MessageUnion>
unionInterface,
Class<? extends MessageUnion>
unionCase, int tag) {
if (!unionmap.containsKey(unionInterface)) {
Modified: gnunet-java/src/main/java/org/gnunet/core/Core.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/core/Core.java 2014-02-03 23:00:30 UTC
(rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/core/Core.java 2014-02-03 23:03:52 UTC
(rev 32181)
@@ -116,7 +116,8 @@
final public MessageTransmitter transmitter;
final public AbsoluteTime deadline;
- public NotifyTransmitReadyRequest(int priority, int size, PeerIdentity
target, RelativeTime timeout, MessageTransmitter transmitter) {
+ public NotifyTransmitReadyRequest(int priority, int size, PeerIdentity
target,
+ RelativeTime timeout,
MessageTransmitter transmitter) {
this.deadline = timeout.toAbsolute();
this.priority = priority;
this.size = size;
@@ -197,6 +198,7 @@
}
public void visit(SendMessageReady m) {
+ logger.debug("got SendMessageReady");
RequestIdentification rid = new RequestIdentification(m.smrId,
m.peer);
NotifyTransmitReadyRequest req = ntrRequests.getRequest(rid);
@@ -232,6 +234,7 @@
@Override
public void handleError() {
+ logger.warn("Error receiving from the transport service.");
if (disconnectHandler != null) {
for (PeerIdentity e : connectedPeers.keySet()) {
disconnectHandler.onDisconnect(e);
@@ -285,7 +288,8 @@
}
int id = connectedPeers.get(target);
connectedPeers.put(target, id+1);
- NotifyTransmitReadyRequest notifyRequest = new
NotifyTransmitReadyRequest(priority, size, target, maxdelay, transmitter);
+ NotifyTransmitReadyRequest notifyRequest = new
NotifyTransmitReadyRequest(priority, size, target,
+ maxdelay, transmitter);
notifyRequest.smrId = id;
RequestIdentification rid = new
RequestIdentification(notifyRequest.smrId, target);
return ntrRequests.addRequest(rid, notifyRequest);
Modified: gnunet-java/src/main/java/org/gnunet/core/SendMessage.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/core/SendMessage.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/core/SendMessage.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -62,7 +62,7 @@
/**
* Always 0.
*/
- @UInt64
+ @UInt32
public int reserved;
@NestedMessage(newFrame = true)
Modified: gnunet-java/src/main/java/org/gnunet/gns/GnsRecord.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/gns/GnsRecord.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/gns/GnsRecord.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -1,86 +1,129 @@
-/*
- This file is part of GNUnet.
- (C) 2012, 2013 Christian Grothoff (and other contributing authors)
+package org.gnunet.gns;
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, 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
- General Public License for more details.
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.Maps;
+import org.gnunet.construct.*;
+import org.gnunet.gns.records.RecordData;
+import org.gnunet.gns.records.UnknownRecordData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
-package org.gnunet.gns;
+public class GnsRecord implements Message {
+ private static final Logger logger = LoggerFactory
+ .getLogger(GnsRecord.class);
-import org.gnunet.construct.Message;
-import org.gnunet.construct.UInt32;
-import org.gnunet.construct.UInt64;
-import org.gnunet.construct.VariableSizeIntegerArray;
+ private static boolean registryInitialized;
-/**
- * A GNS record.
- */
-public class GnsRecord implements Message {
+ private static BiMap<String,Long> recordTypeMap = HashBiMap.create();
+ private static Map<Long,Class> recordClassMap = Maps.newHashMap();
+
/**
- * No special options.
+ * Expiration, either absolute or relative time depending on 'flags'.
*/
- public static final int FLAG_NONE = 0;
- /**
- * No special options.
- */
- public static final int FLAG_PRIVATE = 2;
- /**
- * This record was added automatically by the system
- * and is pending user confimation.
- */
- public static final int FLAG_PENDING = 4;
- /**
- * This expiration time of the record is a relative
- * time (not an absolute time).
- */
- public static final int FLAG_RELATIVE_EXPIRATION = 8;
- /**
- * This record should not be used unless all (other) records with an
absolute
- * expiration time have expired.
- */
- public static final int FLAG_SHADOW_RECOD = 8;
- /**
- * Either absolute or relative expiration time,
- * depending on 'flags'.
- */
@UInt64
- public long expirationTime;
+ public long expiration;
/**
- * Size of the record data.
+ * Size of 'recordDataBytes'.
*/
@UInt32
- public int dataSize;
+ public long dataSize;
/**
- * Type of the record.
+ * Type ID of this record.
*/
@UInt32
- public int recordType;
+ public long recordType;
- /**
- * Flags for the record.
- */
@UInt32
- int flags;
+ public long flags;
- /**
- * Binary value stored in the GNS record.
- */
- @VariableSizeIntegerArray(lengthField = "dataSize", bitSize = 8, signed =
false)
- byte[] data;
+ @VariableSizeIntegerArray(lengthField = "dataSize", signed = true, bitSize
= 8)
+ public byte[] recordDataBytes;
+ public static void initializeRegistry() {
+ if (registryInitialized)
+ return;
+ Class<?>[] classes = MessageLoader.getUnionCases(RecordData.class);
+ for (Class<?> aClass : classes) {
+ String recordTypeString;
+ try {
+ Field field = aClass.getField("recordTypeString");
+ recordTypeString = (String) field.get(null);
+ } catch (NoSuchFieldException e) {
+ logger.warn("RecordData class {} has no recordTypeString
field");
+ continue;
+ } catch (IllegalAccessException e) {
+ logger.warn("RecordData class {} can't access recordTypeString
field");
+ continue;
+ }
+
+ long recordTypeId = MessageLoader.getUnionTag(RecordData.class,
(Class<? extends MessageUnion>) aClass);
+ recordTypeMap.put(recordTypeString, recordTypeId);
+ recordClassMap.put(recordTypeId, aClass);
+ }
+ registryInitialized = true;
+ }
+
+ public RecordData getRecordData() {
+ initializeRegistry();
+ Class cls = recordClassMap.get(recordType);
+ if (null == cls) {
+ UnknownRecordData unknownRecordData = new UnknownRecordData();
+ unknownRecordData.data = recordDataBytes;
+ }
+ return (RecordData) Construct.parseAs(recordDataBytes, cls);
+ }
+
+ public static GnsRecord createFromString(String typeString, String
content) {
+ long typeId = getIdFromString(typeString);
+ if (typeId < 0)
+ return null;
+ return createFromString(typeId, content);
+ }
+
+ public static GnsRecord createFromString(long typeId, String content) {
+ initializeRegistry();
+ Class cls = recordClassMap.get(typeId);
+ if (null == cls) {
+ return null;
+ }
+ Method mth;
+ try {
+ mth = cls.getMethod("createFromString", String.class);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ try {
+ return (GnsRecord) mth.invoke(null, content);
+ } catch (IllegalAccessException e) {
+ return null;
+ } catch (InvocationTargetException e) {
+ return null;
+ }
+ }
+
+ public static String getStringFromId(long typeId) {
+ initializeRegistry();
+ if (!recordTypeMap.inverse().containsKey(typeId)) {
+ return null;
+ }
+ return recordTypeMap.inverse().get(typeId);
+ }
+
+ public static long getIdFromString(String typeString) {
+ initializeRegistry();
+ if (!recordTypeMap.containsKey(typeString)) {
+ return -1;
+ }
+ return recordTypeMap.get(typeString);
+ }
}
Modified:
gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupMessage.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupMessage.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupMessage.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -57,7 +57,7 @@
* the type of record to look up
*/
@Int32
- public int type;
+ public long type;
/**
* The key for shorten, if haveKey is set
Modified:
gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupResultMessage.java
===================================================================
---
gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupResultMessage.java
2014-02-03 23:00:30 UTC (rev 32180)
+++
gnunet-java/src/main/java/org/gnunet/gns/messages/ClientLookupResultMessage.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -43,8 +43,6 @@
import org.gnunet.construct.*;
import org.gnunet.gns.GnsRecord;
import org.gnunet.util.GnunetMessage;
-import org.gnunet.util.crypto.EcdsaPrivateKey;
-import org.gnunet.util.crypto.EcdsaPublicKey;
/**
* Message GNS service to client as a response to a lookup request.
@@ -57,6 +55,9 @@
@UInt32
public long id;
+ /**
+ * Number of records.
+ */
@UInt32
public long recordCount;
Modified: gnunet-java/src/main/java/org/gnunet/identity/Identity.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/identity/Identity.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/identity/Identity.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -348,6 +348,7 @@
@Override
public void handleError() {
logger.warn("identity service disconnected");
+ // FIXME: should have exp. backoff
client.reconnect();
}
Modified: gnunet-java/src/main/java/org/gnunet/peerinfo/PeerInfo.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/peerinfo/PeerInfo.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/peerinfo/PeerInfo.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -35,7 +35,7 @@
*/
public class PeerInfo {
private static final Logger logger = LoggerFactory
- .getLogger(AbsoluteTime.class);
+ .getLogger(PeerInfo.class);
/**
* Client that connects to the peerinfo service.
Modified: gnunet-java/src/main/java/org/gnunet/testing/TestingFixture.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/testing/TestingFixture.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/testing/TestingFixture.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -3,12 +3,23 @@
import org.gnunet.util.Scheduler;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.Timeout;
/**
* Default JUnit4 fixture methods for gnunet-java tests.
* Resets the scheduler properly.
*/
public class TestingFixture {
+
+ /**
+ * All gnunet-java tests that inherit from the fixture
+ * have a 10-second default timeout.
+ * FIXME: for a longer timeout, which has precedence?
+ */
+ @Rule
+ public Timeout defaultTimeout = new Timeout(10000);
+
@Before
public void beginGNJTest() {
Scheduler.forceReset();
Modified: gnunet-java/src/main/java/org/gnunet/transport/Transport.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/transport/Transport.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/transport/Transport.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -10,6 +10,8 @@
import org.gnunet.transport.messages.RequestConnectMessage;
import org.gnunet.transport.messages.StartMessage;
import org.gnunet.util.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
@@ -20,7 +22,8 @@
* @author Florian Dold
*/
public class Transport {
-
+ private static final Logger logger = LoggerFactory
+ .getLogger(Transport.class);
/**
* Client that connects to the transport service,
*/
@@ -55,6 +58,8 @@
}
@Override
public void handleError() {
+ logger.warn("Error receiving from the transport service,
reconnecting.");
+ // FIXME: there is no backoff ...
client.reconnect();
sendStart();
}
@@ -113,10 +118,7 @@
/**
* Obtain the HELLO message for this peer.
*
- * @param rec function to call with the HELLO, sender will be our peer
- * identity; message and sender will be NULL on timeout
- * (handshake with transport service pending/failed).
- * cost estimate will be 0.
+ * @param rec function to call with the HELLO
* @return handle to cancel the operation
*/
Cancelable getHello(final HelloUpdateCallback rec) {
Modified:
gnunet-java/src/main/java/org/gnunet/transport/messages/StartMessage.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/transport/messages/StartMessage.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/transport/messages/StartMessage.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -1,3 +1,22 @@
+/*
+ This file is part of GNUnet.
+ (C) 2014 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
package org.gnunet.transport.messages;
import org.gnunet.construct.NestedMessage;
@@ -7,7 +26,6 @@
import org.gnunet.util.PeerIdentity;
/**
- *
* Message from the transport service to the library
* asking to check if both processes agree about this
* peers identity.
Modified: gnunet-java/src/main/java/org/gnunet/util/Connection.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/Connection.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/Connection.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -188,6 +188,7 @@
logger.debug("ready to receive");
try {
processedMessage = false;
+ logger.debug("reading into mst ...");
int n = mst.readFrom(connectionChannel, true);
logger.debug("read {} bytes into mst", n);
if (processedMessage) {
@@ -263,7 +264,7 @@
throw new IOError(e);
}
if (transmitBuffer.remaining() == 0) {
- //logger.debug("sent " + transmitBuffer.position() + "bytes
complete message");
+ logger.debug("transmit buffer fully sent");
if (nextTransmitHelper == null) {
currentTransmitHelper = null;
} else {
Modified: gnunet-java/src/main/java/org/gnunet/util/MessageStreamTokenizer.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/MessageStreamTokenizer.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/MessageStreamTokenizer.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -125,6 +125,7 @@
*/
public int readFrom(ReadableByteChannel source, boolean oneShot) throws
IOException {
int n;
+ logger.debug("reading in mst from channel");
n = source.read(buffer);
logger.debug("read {} bytes from channel", n);
if (oneShot) {
Modified: gnunet-java/src/main/java/org/gnunet/util/PeerIdentity.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/PeerIdentity.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/PeerIdentity.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -28,31 +28,21 @@
/**
- * Identity of a peer, stored as 512-bit public key.
+ * Identity of a peer. Wrapper for an
+ * EdDSA key.
*/
public class PeerIdentity implements Message {
- @FixedSizeIntegerArray(length = 64, signed = false, bitSize = 8)
+ @FixedSizeIntegerArray(length = 32, signed = false, bitSize = 8)
public byte[] data;
- static final String HEXES = "0123456789ABCDEF";
-
/**
* Creates a zero-filled peer identity
*/
public PeerIdentity() {
- data = new byte[64];
+ data = new byte[32];
}
- public String getHex() {
- final StringBuilder hex = new StringBuilder( 2 * data.length );
- for (final byte b : data) {
- hex.append(HEXES.charAt((b & 0xF0) >> 4))
- .append(HEXES.charAt((b & 0x0F)));
- }
- return hex.toString();
- }
-
public String toString() {
return Strings.dataToString(data);
}
Modified: gnunet-java/src/main/java/org/gnunet/util/RelativeTime.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/RelativeTime.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/RelativeTime.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -44,6 +44,8 @@
public static final RelativeTime ZERO = new RelativeTime(0);
public static final RelativeTime FOREVER = new
RelativeTime(Long.MAX_VALUE);
+ public static final RelativeTime STD_BACKOFF = MILLISECOND;
+ public static final RelativeTime STD_BACKOFF_MAX = MINUTE.multiply(15);
/**
* Time offset in microseconds.
@@ -227,7 +229,11 @@
}
}
- public Object getSeconds() {
+ public RelativeTime backoff() {
+ return RelativeTime.min(STD_BACKOFF_MAX, this.multiply(2));
+ }
+
+ public long getSeconds() {
return rel_value_us / (1000 * 1000);
}
}
Modified: gnunet-java/src/main/java/org/gnunet/util/Scheduler.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/Scheduler.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/Scheduler.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -32,85 +32,352 @@
/**
* Schedule computations using continuation passing style.
- * <p/>
- * By design, it is not safe to scheduler tasks from different threads.
- * When threads can't be avoided, they should communicate with the scheduler by
- * a pipe.
*
+ * All operations, per default, use the thread-local scheduler.
+ *
* @author Florian Dold
*/
public class Scheduler {
private static final Logger logger = LoggerFactory
.getLogger(Scheduler.class);
- /**
- * Task that we are currently executing, or null if no task is currently
running.
- */
- private static TaskIdentifier activeTask = null;
- /**
- * Number of tasks in the ready lists, that is, number of tasks that is
ready to run
- * (all prerequisites are fulfilled).
- */
- private static volatile int readyCount = 0;
+ static ThreadLocal<SchedulerInstance> threadScheduler = new
ThreadLocal<SchedulerInstance>() {
+ @Override
+ protected SchedulerInstance initialValue() {
+ return new SchedulerInstance();
+ }
+ };
- /**
- * Priority for Tasks, in order if ascending priority.
- * When two tasks are ready, the one with the higher priority is executed
first.
- */
- public enum Priority {
- IDLE, BACKGROUND, DEFAULT, HIGH, UI, URGENT, SHUTDOWN;
+ private static class SchedulerInstance {
/**
- * how many different priorities do we have?
+ * Task that we are currently executing, or null if no task is
currently running.
*/
- private static final int numberOfPriorities = Priority.values().length;
- }
+ TaskIdentifier activeTask = null;
- /**
- * For every priority, there is a list of tasks that is definitely ready
to run.
- */
- @SuppressWarnings("unchecked")
- final private static LinkedList<TaskIdentifier>[] readyLists = new
LinkedList[Priority.numberOfPriorities];
+ /**
+ * Number of tasks in the ready lists, that is, number of tasks that
is ready to run
+ * (all prerequisites are fulfilled).
+ */
+ int readyCount = 0;
- static {
- for (int i = 0; i < Priority.numberOfPriorities; ++i) {
- readyLists[i] = new LinkedList<TaskIdentifier>();
+ /**
+ * Selector, used to check file descriptors for readiness.
+ */
+ Selector selector = null;
+
+ /**
+ * For every priority, there is a list of tasks that is definitely
ready to run.
+ */
+ @SuppressWarnings("unchecked")
+ final LinkedList<TaskIdentifier>[] readyLists = new
LinkedList[Priority.numberOfPriorities];
+
+ /**
+ * true iff the scheduler is currently running.
+ */
+ boolean schedulerRunning = false;
+
+
+ /**
+ * Pending tasks are waiting for an event. Each pending task has a
(possibly infinitely long)
+ * deadline after which the task is executed regardless of the
prerequisites.
+ */
+ final Queue<TaskIdentifier> pending = new
PriorityQueue<TaskIdentifier>(5, new Comparator
+ <TaskIdentifier>() {
+ @Override
+ public int compare(TaskIdentifier a, TaskIdentifier b) {
+ return a.deadline.compareTo(b.deadline);
+ }
+ });
+
+
+ /**
+ * Check if the system is still life. Trigger disconnect if we have
tasks, but
+ * none of them give us lifeness.
+ *
+ * @return true to continue the main loop, false to exit
+ */
+ private boolean checkLiveness() {
+ if (readyCount > 0) {
+ return true;
+ }
+ for (TaskIdentifier t : pending) {
+ if (t.lifeness) {
+ return true;
+ }
+ }
+ // trigger shutdown if we still have pending tasks, but none of
them has lifeness
+ if (!pending.isEmpty()) {
+ logger.debug("tasks pending but not alive -- disconnect");
+ shutdown();
+ return true;
+ }
+ return false;
}
- }
- /**
- * Selector, used to check file descriptors for readiness.
- */
- private static Selector selector = null;
+ /**
+ * Queue a Task for execution.
+ *
+ * @param tid TaskIdentifier of the ready task
+ */
+ private void queueReady(TaskIdentifier tid) {
+ int idx = tid.priority.ordinal();
+ readyLists[idx].add(tid);
+ readyCount++;
+ pending.remove(tid);
+ }
- static {
- try {
- selector = SelectorProvider.provider().openSelector();
- } catch (final IOException e) {
- // what to do here?
- logger.error("fatal: cannot create selector");
- System.exit(-1);
+ void addContinuation(Task task, EnumSet<Reason> reasons) {
+ readyLists[Priority.DEFAULT.ordinal()].add(new
TaskIdentifier(this, task, reasons));
+ readyCount += 1;
}
+
+ /**
+ * Queue all tasks with expired timeout.
+ *
+ * @return the minimum time to wait until the next timeout expiry
+ */
+ private RelativeTime handleTimeouts() {
+ RelativeTime timeout = RelativeTime.FOREVER;
+
+ // check if any timeouts occurred
+ while (true) {
+ TaskIdentifier t = pending.peek();
+ if (t == null) {
+ break;
+ }
+ RelativeTime remaining = t.deadline.getRemaining();
+ if (remaining.getMicroseconds() <= 0) {
+ t.deregister();
+ t.ctx.reasons = EnumSet.of(Reason.TIMEOUT);
+ queueReady(t);
+ } else {
+ timeout = remaining;
+ break;
+ }
+ }
+ return timeout;
+ }
+
+
+ public SchedulerInstance() {
+ for (int i = 0; i < Priority.numberOfPriorities; ++i) {
+ readyLists[i] = new LinkedList<TaskIdentifier>();
+ }
+
+ try {
+ selector = SelectorProvider.provider().openSelector();
+ } catch (final IOException e) {
+ // what to do here?
+ logger.error("fatal: cannot create selector");
+ System.exit(-1);
+ }
+ }
+
+
+ /**
+ * Select on channels and queue tasks that become executable.
+ *
+ * @param timeout timeout for select
+ */
+ private void handleSelect(RelativeTime timeout) {
+ // gnunet-java uses microseconds, but the select api uses
milliseconds
+ long timeout_ms = timeout.getMicroseconds() / 1000;
+ try {
+ // selector.select(0) would block indefinitely
(counter-intuitive, java's fault)
+ if (timeout_ms == 0) {
+ selector.selectNow();
+ } else if (timeout.isForever()) {
+ // fixme: we should only do this if we are sure there are
tasks that select on something
+ logger.debug("selecting, timeout=forever");
+ selector.select(0);
+ } else {
+ selector.select(timeout_ms);
+ }
+ } catch (IOException e) {
+ throw new IOError(e);
+ }
+
+ logger.debug("select over");
+
+ // we use a set so that we don't execute any task twice
+ Collection<TaskIdentifier> executableTasks = new
HashSet<TaskIdentifier>();
+ for (SelectionKey sk : selector.selectedKeys()) {
+ @SuppressWarnings("unchecked")
+ LinkedList<TaskInterestOps> subscribers =
(LinkedList<TaskInterestOps>) sk.attachment();
+ for (TaskInterestOps ops : subscribers) {
+ if ((sk.readyOps() & ops.interestOps) != 0) {
+ executableTasks.add(ops.tid);
+ addReasonsFromInterestOp(ops.tid.ctx.reasons,
sk.readyOps() & ops.interestOps);
+ }
+ }
+ }
+ for (TaskIdentifier tt : executableTasks) {
+ // cancel subscriptions to other events, we can execute now!
+ tt.deregister();
+ queueReady(tt);
+ }
+ }
+
+
+ /**
+ * Initialize and run scheduler. This function will return when all
tasks
+ * have completed.
+ */
+ public void run() {
+ run(null);
+ }
+
+ /**
+ * Initialize and run scheduler. This function will return when all
tasks
+ * have completed.
+ *
+ * @param initialTask the initial task to run immediately
+ */
+ public void run(Task initialTask) {
+ logger.debug("running scheduler");
+ if (schedulerRunning) {
+ throw new AssertionError("Scheduler already running");
+ }
+ schedulerRunning = true;
+ try {
+ runUnchecked(initialTask);
+ } finally {
+ logger.debug("cleaning up after scheduler ran");
+ // ensure that after run returns, the scheduler is in its
initial state,
+ // even though there was an exception (e.g. after a test case
that expects an exception)
+ forceReset();
+ }
+ }
+
+ /**
+ * Request the shutdown of the scheduler. Marks all currently pending
tasks as
+ * ready because of disconnect. This will cause all tasks to run (as
soon as
+ * possible, respecting priorities and prerequisite tasks). Note that
tasks
+ * scheduled AFTER this call may still be delayed arbitrarily.
+ */
+ public void shutdown() {
+ // queueReady() while iterating would yield concurrent
modification exn otherwise
+ for (TaskIdentifier tid : new ArrayList<TaskIdentifier>(pending)) {
+ tid.ctx.reasons.add(Reason.SHUTDOWN);
+ queueReady(tid);
+ }
+ pending.clear();
+ }
+
+ /**
+ * Reset the scheduler forcefully.
+ * Intended to be used internally in the Scheduler, as well as in test
teardown.
+ */
+ public void forceReset() {
+ schedulerRunning = false;
+ readyCount = 0;
+ activeTask = null;
+ for (int i = 0; i < Priority.numberOfPriorities; ++i) {
+ readyLists[i] = Lists.newLinkedList();
+ }
+ pending.clear();
+ }
+
+
+ public boolean hasTasks() {
+ return readyCount != 0 || !pending.isEmpty();
+ }
+
+ /**
+ * Execute tasks until either
+ * <ul>
+ * <li>there are no ready tasks</li>
+ * <li>there is a pending task (which may be of higher priority)</li>
+ * </ul>
+ */
+ private void runReady() {
+ do {
+ if (readyCount == 0) {
+ return;
+ }
+ // start executing from the highest priority down to 0
+ for (int p = Priority.numberOfPriorities - 1; p >= 0; p--) {
+ // execute all tasks with priority p
+ LinkedList<TaskIdentifier> queue = readyLists[p];
+ while (!queue.isEmpty()) {
+ TaskIdentifier tid = queue.removeFirst();
+ readyCount--;
+ tid.run();
+ }
+ }
+ } while (pending.size() == 0);
+ }
+
+ /**
+ * Initialize and run scheduler. This function will return when all
tasks
+ * have completed. Don't check if the scheduler is already running or
not.
+ *
+ * @param initialTask the initial task to run immediately
+ */
+ private void runUnchecked(Task initialTask) {
+ if (initialTask != null) {
+ addContinuation(initialTask, EnumSet.of(Reason.STARTUP));
+ }
+
+ // the gnunet main loop
+ while (checkLiveness()) {
+ RelativeTime nextTimeout = handleTimeouts();
+ if (nextTimeout.getMicroseconds() < 0) {
+ logger.warn("negative timeout for select");
+ }
+
+ // don't select if there are no tasks; we are done!
+ if (readyCount == 0 && pending.isEmpty()) {
+ return;
+ }
+
+ // don't block in select if we have tasks ready to run!
+ if (readyCount > 0) {
+ handleSelect(RelativeTime.ZERO);
+ } else {
+ handleSelect(nextTimeout);
+ }
+ runReady();
+ }
+
+ if (readyCount != 0) {
+ throw new AssertionError("tasks ready after scheduler ran
(count)");
+ }
+
+ for (List readyList : readyLists) {
+ if (!readyList.isEmpty()) {
+ throw new AssertionError("tasks ready after scheduler ran
(list)");
+ }
+ }
+
+ if (pending.size() != 0) {
+ throw new AssertionError("pending tasks after scheduler ran");
+ }
+
+ if (activeTask != null) {
+ throw new AssertionError("active task after scheduler ran");
+ }
+ }
+
}
- /**
- * true iff the scheduler is currently running.
- */
- private static boolean schedulerRunning = false;
/**
- * Pending tasks are waiting for an event. Each pending task has a
(possibly infinitely long)
- * deadline after which the task is executed regardless of the
prerequisites.
+ * Priority for Tasks, in order if ascending priority.
+ * When two tasks are ready, the one with the higher priority is executed
first.
*/
- final private static Queue<TaskIdentifier> pending = new
PriorityQueue<TaskIdentifier>(5, new Comparator
- <TaskIdentifier>() {
- @Override
- public int compare(TaskIdentifier a, TaskIdentifier b) {
- return a.deadline.compareTo(b.deadline);
- }
- });
+ public enum Priority {
+ IDLE, BACKGROUND, DEFAULT, HIGH, UI, URGENT, SHUTDOWN;
+ /**
+ * how many different priorities do we have?
+ */
+ private static final int numberOfPriorities = Priority.values().length;
+ }
+
+
/**
* Reasons for executing a task.
*/
@@ -140,6 +407,11 @@
* Manage subscriptions for selection events on channels.
*/
private static class Subscriptions {
+ /**
+ * Selector to use for subscription operations.
+ */
+ private final Selector selector;
+
private static class ChannelInterest {
SelectableChannel channel;
int interestOps;
@@ -211,6 +483,10 @@
key.interestOps(remainingInterestOps);
}
}
+
+ public Subscriptions(Selector selector) {
+ this.selector = selector;
+ }
}
/**
@@ -233,8 +509,10 @@
private final Priority priority;
private final AbsoluteTime deadline;
private final Subscriptions subscriptions;
+ private SchedulerInstance scheduler;
- public TaskIdentifier(Task task, EnumSet<Reason> reasons) {
+ public TaskIdentifier(SchedulerInstance scheduler, Task task,
EnumSet<Reason> reasons) {
+ this.scheduler = scheduler;
this.ctx.reasons = reasons;
this.task = task;
lifeness = true;
@@ -243,7 +521,8 @@
subscriptions = null;
}
- public TaskIdentifier(TaskConfiguration tc) {
+ public TaskIdentifier(SchedulerInstance scheduler, TaskConfiguration
tc) {
+ this.scheduler = scheduler;
this.task = tc.task;
this.subscriptions = tc.subscriptions;
this.deadline = tc.deadline;
@@ -259,11 +538,11 @@
if (isCanceled) {
return;
}
- TaskIdentifier old = activeTask;
- activeTask = this;
+ TaskIdentifier old = scheduler.activeTask;
+ scheduler.activeTask = this;
task.run(ctx);
hasRun = true;
- activeTask = old;
+ scheduler.activeTask = old;
}
@Override
@@ -275,7 +554,7 @@
throw new AssertionError("task canceled twice");
}
isCanceled = true;
- pending.remove(this);
+ scheduler.pending.remove(this);
}
public void deregister() {
@@ -296,6 +575,8 @@
private Subscriptions subscriptions;
+ private SchedulerInstance scheduler;
+
/**
* Create a TaskIdentifier.
*
@@ -304,26 +585,34 @@
* (but only queued directly)
* @param task task to run with this TaskIdentifier
*/
- TaskConfiguration(RelativeTime delay, Task task) {
+ TaskConfiguration(SchedulerInstance scheduler, RelativeTime delay,
Task task) {
if (delay == null)
throw new AssertionError("task delay may not be 'null'");
+ this.scheduler = scheduler;
this.task = task;
this.deadline = delay.toAbsolute();
}
+ TaskConfiguration(RelativeTime delay, Task task) {
+ this(threadScheduler.get(), delay, task);
+ }
+
public TaskIdentifier schedule() {
+ return schedule(Scheduler.threadScheduler.get());
+ }
+ public TaskIdentifier schedule(SchedulerInstance scheduler) {
if (priority == null) {
- if (activeTask != null) {
- priority = activeTask.priority;
+ if (scheduler.activeTask != null) {
+ priority = scheduler.activeTask.priority;
} else {
priority = Priority.DEFAULT;
}
}
- TaskIdentifier tid = new TaskIdentifier(this);
+ TaskIdentifier tid = new TaskIdentifier(scheduler, this);
if (subscriptions != null)
subscriptions.apply(tid);
- pending.add(tid);
+ scheduler.pending.add(tid);
return tid;
}
@@ -332,7 +621,7 @@
throw new AssertionError("channel may not be null");
}
if (subscriptions == null)
- subscriptions = new Subscriptions();
+ subscriptions = new Subscriptions(scheduler.selector);
subscriptions.add(channel, event);
}
}
@@ -342,7 +631,7 @@
* the same priority.
*/
public static void addContinuation(Task task, EnumSet<Reason> reasons) {
- queueReady(new TaskIdentifier(task, reasons));
+ threadScheduler.get().addContinuation(task, reasons);
}
/**
@@ -366,7 +655,7 @@
*/
public static TaskIdentifier addDelayed(RelativeTime delay, Task task) {
TaskConfiguration tid = new TaskConfiguration(delay, task);
- return tid.schedule();
+ return tid.schedule(threadScheduler.get());
}
/**
@@ -382,10 +671,32 @@
SelectableChannel chan, Task task) {
TaskConfiguration tid = new TaskConfiguration(timeout, task);
tid.addSelectEvent(chan, SelectionKey.OP_READ);
- return tid.schedule();
+ return tid.schedule(threadScheduler.get());
}
/**
+ * Initialize and run scheduler. This function will return when all tasks
+ * have completed.
+ */
+ public static void run() {
+ threadScheduler.get().run();
+ }
+
+ /**
+ * Initialize and run scheduler. This function will return when all tasks
+ * have completed.
+ *
+ * @param initialTask the initial task to run immediately
+ */
+ public static void run(Task initialTask) {
+ threadScheduler.get().run(initialTask);
+ }
+
+ public static boolean hasTasks() {
+ return threadScheduler.get().hasTasks();
+ }
+
+ /**
* Add a task to run after the specified delay, or after the given channel
* is ready to write, whichever occurs first.
*
@@ -398,73 +709,11 @@
SelectableChannel chan, Task task) {
TaskConfiguration tid = new TaskConfiguration(timeout, task);
tid.addSelectEvent(chan, SelectionKey.OP_WRITE);
- return tid.schedule();
+ return tid.schedule(threadScheduler.get());
}
- /**
- * Check if the system is still life. Trigger disconnect if we have tasks,
but
- * none of them give us lifeness.
- *
- * @return true to continue the main loop, false to exit
- */
- private static boolean checkLiveness() {
- if (readyCount > 0) {
- return true;
- }
- for (TaskIdentifier t : pending) {
- if (t.lifeness) {
- return true;
- }
- }
- // trigger shutdown if we still have pending tasks, but none of them
has lifeness
- if (!pending.isEmpty()) {
- logger.debug("tasks pending but not alive -- disconnect");
- shutdown();
- return true;
- }
- return false;
- }
- /**
- * Queue a Task for execution.
- *
- * @param tid TaskIdentifier of the ready task
- */
- private static void queueReady(TaskIdentifier tid) {
- int idx = tid.priority.ordinal();
- readyLists[idx].add(tid);
- readyCount++;
- pending.remove(tid);
- }
- /**
- * Queue all tasks with expired timeout.
- *
- * @return the minimum time to wait until the next timeout expiry
- */
- private static RelativeTime handleTimeouts() {
- RelativeTime timeout = RelativeTime.FOREVER;
-
- // check if any timeouts occurred
- while (true) {
- TaskIdentifier t = pending.peek();
- if (t == null) {
- break;
- }
- RelativeTime remaining = t.deadline.getRemaining();
- if (remaining.getMicroseconds() <= 0) {
- t.deregister();
- t.ctx.reasons = EnumSet.of(Reason.TIMEOUT);
- queueReady(t);
- } else {
- timeout = remaining;
- break;
- }
- }
- return timeout;
- }
-
-
private static void addReasonsFromInterestOp(EnumSet<Reason> reasons, int
interestOps) {
if ((interestOps & SelectionKey.OP_READ) != 0)
reasons.add(Reason.READ_READY);
@@ -476,194 +725,8 @@
reasons.add(Reason.ACCEPT_READY);
}
- /**
- * Select on channels and queue tasks that become executable.
- *
- * @param timeout timeout for select
- */
- private static void handleSelect(RelativeTime timeout) {
- // gnunet-java uses microseconds, but the select api uses milliseconds
- long timeout_ms = timeout.getMicroseconds() / 1000;
- try {
- // selector.select(0) would block indefinitely (counter-intuitive,
java's fault)
- if (timeout_ms == 0) {
- selector.selectNow();
- } else if (timeout.isForever()) {
- // fixme: we should only do this if we are sure there are
tasks that select on something
- logger.debug("selecting, timeout=forever");
- selector.select(0);
- } else {
- selector.select(timeout_ms);
- }
- } catch (IOException e) {
- throw new IOError(e);
- }
- logger.debug("select over");
-
- // we use a set so that we don't execute any task twice
- Collection<TaskIdentifier> executableTasks = new
HashSet<TaskIdentifier>();
- for (SelectionKey sk : selector.selectedKeys()) {
- @SuppressWarnings("unchecked")
- LinkedList<TaskInterestOps> subscribers =
(LinkedList<TaskInterestOps>) sk.attachment();
- for (TaskInterestOps ops : subscribers) {
- if ((sk.readyOps() & ops.interestOps) != 0) {
- executableTasks.add(ops.tid);
- addReasonsFromInterestOp(ops.tid.ctx.reasons,
sk.readyOps() & ops.interestOps);
- }
- }
- }
- for (TaskIdentifier tt : executableTasks) {
- // cancel subscriptions to other events, we can execute now!
- tt.deregister();
- queueReady(tt);
- }
- }
-
/**
- * Initialize and run scheduler. This function will return when all tasks
- * have completed.
- */
- public static void run() {
- run(null);
- }
-
- /**
- * Initialize and run scheduler. This function will return when all tasks
- * have completed.
- *
- * @param initialTask the initial task to run immediately
- */
- public static void run(Task initialTask) {
- logger.debug("running scheduler");
- if (schedulerRunning) {
- throw new AssertionError("Scheduler already running");
- }
- schedulerRunning = true;
- try {
- run_unchecked(initialTask);
- } finally {
- logger.debug("cleaning up after scheduler ran");
- // ensure that after run returns, the scheduler is in its initial
state,
- // even though there was an exception (e.g. after a test case that
expects an exception)
- forceReset();
- }
- }
-
- /**
- * Initialize and run scheduler. This function will return when all tasks
- * have completed. Don't check if the scheduler is already running or not.
- *
- * @param initialTask the initial task to run immediately
- */
- private static void run_unchecked(Task initialTask) {
- if (initialTask != null) {
- addContinuation(initialTask, EnumSet.of(Reason.STARTUP));
- }
-
- // the gnunet main loop
- while (checkLiveness()) {
- RelativeTime nextTimeout = handleTimeouts();
- if (nextTimeout.getMicroseconds() < 0) {
- logger.warn("negative timeout for select");
- }
-
- // don't select if there are no tasks; we are done!
- if (readyCount == 0 && pending.isEmpty()) {
- return;
- }
-
- // don't block in select if we have tasks ready to run!
- if (readyCount > 0) {
- handleSelect(RelativeTime.ZERO);
- } else {
- handleSelect(nextTimeout);
- }
- runReady();
- }
-
- if (readyCount != 0) {
- throw new AssertionError("tasks ready after scheduler ran
(count)");
- }
-
- for (List readyList : Scheduler.readyLists) {
- if (!readyList.isEmpty()) {
- throw new AssertionError("tasks ready after scheduler ran
(list)");
- }
- }
-
- if (pending.size() != 0) {
- throw new AssertionError("pending tasks after scheduler ran");
- }
-
- if (activeTask != null) {
- throw new AssertionError("active task after scheduler ran");
- }
- }
-
-
- /**
- * Execute tasks until either
- * <ul>
- * <li>there are no ready tasks</li>
- * <li>there is a pending task (which may be of higher priority)</li>
- * </ul>
- */
- private static void runReady() {
- do {
- if (readyCount == 0) {
- return;
- }
- // start executing from the highest priority down to 0
- for (int p = Priority.numberOfPriorities - 1; p >= 0; p--) {
- // execute all tasks with priority p
- LinkedList<TaskIdentifier> queue = readyLists[p];
- while (!queue.isEmpty()) {
- TaskIdentifier tid = queue.removeFirst();
- readyCount--;
- tid.run();
- }
- }
- } while (pending.size() == 0);
-
- }
-
- /**
- * Request the shutdown of the scheduler. Marks all currently pending
tasks as
- * ready because of disconnect. This will cause all tasks to run (as soon
as
- * possible, respecting priorities and prerequisite tasks). Note that tasks
- * scheduled AFTER this call may still be delayed arbitrarily.
- */
- public static void shutdown() {
- // queueReady() while iterating would yield concurrent modification
exn otherwise
- for (TaskIdentifier tid : new ArrayList<TaskIdentifier>(pending)) {
- tid.ctx.reasons.add(Reason.SHUTDOWN);
- queueReady(tid);
- }
- pending.clear();
- }
-
- /**
- * Reset the scheduler forcefully.
- * Intended to be used internally in the Scheduler, as well as in test
teardown.
- */
- public static void forceReset() {
- schedulerRunning = false;
- readyCount = 0;
- activeTask = null;
- for (int i = 0; i < Priority.numberOfPriorities; ++i) {
- readyLists[i] = Lists.newLinkedList();
- }
- pending.clear();
- }
-
-
- public static boolean hasTasks() {
- return readyCount != 0 || !pending.isEmpty();
- }
-
-
- /**
* A handle to a file system object that can be selected on.
*/
public static class FilePipe {
@@ -676,7 +739,11 @@
public Pipe.SourceChannel getSource() {
return filePipeThread.pipe.source();
}
+ }
+ public static void forceReset() {
+ // FIXME: this should reset all schedulers?
+ threadScheduler.get().forceReset();
}
/**
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/DsaPrng.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/DsaPrng.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/DsaPrng.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -41,7 +41,7 @@
private static final int qlen = 32;
/**
- * Compute the HMAC of the fiven data with our current K-value.
+ * Compute the HMAC of the given data with our current K-value.
*
* @param args data
* @return result of the hmac
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -29,10 +29,12 @@
/**
* Private key for elliptic curve Diffie Hellman exchange.
+ * Note that (in contrast to NaCl) the key is encoded
+ * as big endian.
*/
public class EcdhePrivateKey implements Message {
/**
- * Private key byte string, in little endian form.
+ * Private key byte string, in big endian form.
*/
@FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32)
public byte[] d;
@@ -50,7 +52,7 @@
* @return the public key for this private key
*/
public EcdhePublicKey getPublicKey() {
- BigInteger dCoeff = Ed25519.decodeScalar(d);
+ BigInteger dCoeff = this.asCoefficient();
Ed25519 A = Ed25519.B.scalarmult(dCoeff);
return new EcdhePublicKey(A);
}
@@ -62,7 +64,7 @@
* @return key material
*/
public HashCode ecdh(EcdhePublicKey publicKey) {
- BigInteger dCoeff = Ed25519.decodeScalar(d);
+ BigInteger dCoeff = this.asCoefficient();
Ed25519 Q = publicKey.asPoint().scalarmult(dCoeff);
// hash big endian representation of the x-coordinate.
return HashCode.hash(Q.P0.toByteArray());
@@ -79,11 +81,18 @@
privateKey.d = new byte[32];
sr.nextBytes(privateKey.d);
// clear bits so that d mod 8 = 0
- privateKey.d[0] &= (byte) 248;
+ privateKey.d[31] &= (byte) 248;
// make sure the key fits in 255 bits
- privateKey.d[31] &= (byte) 127;
+ privateKey.d[0] &= (byte) 127;
// make sure key does not have lots of leading zeros
- privateKey.d[31] |= (byte) 64;
+ privateKey.d[0] |= (byte) 64;
return privateKey;
}
+
+ public BigInteger asCoefficient() {
+ /* We have a big endian value here ... */
+ return new BigInteger(1, d);
+ }
+
+
}
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -32,7 +32,7 @@
*/
public class EcdsaPrivateKey implements Message {
/**
- * Private key byte string, in little endian form.
+ * Private key byte string, in big endian form.
*/
@FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32)
public byte[] d;
@@ -82,22 +82,23 @@
EcdsaSignature signature = new EcdsaSignature();
DsaPrng prng = new DsaPrng(d, data);
HashCode h = HashCode.hash(data);
- byte[] zData = new byte[32];
- System.arraycopy(h.data, 0, zData, 0, 32);
- BigInteger z = new BigInteger(1, zData);
- BigInteger dCoeff = Ed25519.decodeScalar(d);
+ BigInteger z = new BigInteger(1, h.data);
+ BigInteger dCoeff = this.asCoefficient();
+
while (true) {
BigInteger k = prng.nextK();
Ed25519 P = Ed25519.B.scalarmult(k);
- BigInteger r = P.P0.mod(Ed25519.q);
+ BigInteger r = P.P0.mod(Ed25519.l);
if (r.equals(BigInteger.ZERO))
continue;
- BigInteger s =
k.modInverse(Ed25519.q).multiply(z.add(r.multiply(dCoeff)));
- if (!r.equals(BigInteger.ZERO)) {
- signature.r = Ed25519.encodeScalar(r);
- signature.s = Ed25519.encodeScalar(s);
- return signature;
- }
+ BigInteger kInv = k.modInverse(Ed25519.l);
+ BigInteger v = z.add(r.multiply(dCoeff));
+ BigInteger s = kInv.multiply(v).mod(Ed25519.l);
+ if (s.equals(BigInteger.ZERO))
+ continue;
+ signature.r = Ed25519.encodeScalar(r);
+ signature.s = Ed25519.encodeScalar(s);
+ return signature;
}
}
@@ -107,7 +108,7 @@
* @return the public key for this private key
*/
public EcdsaPublicKey getPublicKey() {
- Ed25519 A = Ed25519.B.scalarmult(Ed25519.decodeScalar(d));
+ Ed25519 A = Ed25519.B.scalarmult(this.asCoefficient());
return new EcdsaPublicKey(A);
}
@@ -123,4 +124,19 @@
sr.nextBytes(privateKey.d);
return privateKey;
}
+
+ public BigInteger asCoefficient() {
+ return new BigInteger(1, d);
+ }
+
+ /**
+ * Key that is set to all zeros.
+ *
+ * @return key that is set to all zeros
+ */
+ public static EcdsaPrivateKey zeroKey() {
+ EcdsaPrivateKey pk = new EcdsaPrivateKey();
+ pk.d = new byte[32];
+ return pk;
+ }
}
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -61,12 +61,13 @@
* Load an ECDSA key from a string.
*
* @param s string with the key data
- * @return a public key
+ * @return a public key, or NULL if 's' not a valid public key encoding
*/
public static EcdsaPublicKey fromString(String s) {
EcdsaPublicKey publicKey = new EcdsaPublicKey();
- Strings.stringToData(s, publicKey.y);
- return publicKey;
+ if (Strings.stringToData(s, publicKey.y))
+ return publicKey;
+ return null;
}
/**
@@ -105,4 +106,12 @@
return result;
}
+ /**
+ * Convert this public key to a point on the Ed25519 curve.
+ *
+ * @return a point corresponding to this key
+ */
+ public Ed25519 asPoint() {
+ return Ed25519.decode(y);
+ }
}
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -62,17 +62,40 @@
* @return whether the signature is valid
*/
public boolean verify(byte[] m, int purpose, EcdsaPublicKey publicKey) {
+ if (publicKey.asPoint().isIdentity()) {
+ throw new AssertionError();
+ }
+
+ if (!publicKey.asPoint().isOnCurve()) {
+ throw new AssertionError();
+ }
+
+ if (!publicKey.asPoint().scalarmult(Ed25519.l).isIdentity()) {
+ throw new AssertionError("invalid public key");
+ }
+
HashCode h = HashCode.hash(m);
- byte[] zData = new byte[32];
- System.arraycopy(h.data, 0, zData, 0, 32);
- BigInteger z = new BigInteger(1, zData);
+ /*
+ byte[] zPart = new byte[32];
+ System.arraycopy(h.data, 0, zPart, 0, 32);
+ for (int i = 0; i < 16; i++) {
+ byte tmp = zPart[i];
+ zPart[i] = zPart[31-i];
+ zPart[31 - i] = tmp;
+ }
+ BigInteger z = new BigInteger(1, zPart);
+ */
+ BigInteger z = new BigInteger(1, h.data);
BigInteger sCoeff = Ed25519.decodeScalar(s);
BigInteger rCoeff = Ed25519.decodeScalar(r);
- BigInteger w = sCoeff.modInverse(Ed25519.q);
- BigInteger u1 = z.multiply(w).mod(Ed25519.q);
- BigInteger u2 = rCoeff.multiply(w).mod(Ed25519.q);
- Ed25519 P = Ed25519.B.scalarmult(u1).add(Ed25519.B.scalarmult(u2));
- return P.P0.equals(rCoeff.mod(Ed25519.q));
+
+ // FIXME: check range of s and r
+ BigInteger w = sCoeff.modInverse(Ed25519.l);
+ BigInteger u1 = z.multiply(w).mod(Ed25519.l);
+ BigInteger u2 = rCoeff.multiply(w).mod(Ed25519.l);
+ // P = u1*B + u2*Q
+ Ed25519 P =
Ed25519.B.scalarmult(u1).add(publicKey.asPoint().scalarmult(u2));
+ return P.P0.mod(Ed25519.l).equals(rCoeff);
}
/**
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/Ed25519.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/Ed25519.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/Ed25519.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -32,7 +32,7 @@
*/
public class Ed25519 {
/**
- * curve parameter b
+ * The curve parameter b.
*/
public static final int b = 256;
/**
@@ -48,11 +48,11 @@
*/
private static final BigInteger qp3 = q.add(BigInteger.valueOf(3));
/**
- * ???
+ * The l parameter (a prime, order of the base point B).
*/
- static final BigInteger l = new
BigInteger("7237005577332262213973186563042994240857116359379907606001950938285454250989");
+ public static final BigInteger l = new
BigInteger("7237005577332262213973186563042994240857116359379907606001950938285454250989");
/**
- * ???
+ * The d parameter (a field element).
*/
private static final BigInteger d = new
BigInteger("-4513249062541557337682894930092624173785641285191125241628941591882900924598840740");
/**
@@ -69,7 +69,7 @@
*/
private static final BigInteger By = new
BigInteger("46316835694926478169428394003475163141307993866256225615783033603165251855960");
/**
- * base point
+ * The chosen base point of order l.
*/
public static final Ed25519 B = new Ed25519(Bx.mod(q),By.mod(q));
@@ -99,7 +99,9 @@
}
/**
- * Create a curve point from its string representation
+ * Create a curve point from its string representation.
+ * Note that returned point is not necessarily a valid
+ * point.
*
* @param s the string representation
* @return a curve point corresponsing to 's'
@@ -111,9 +113,6 @@
x = q.subtract(x);
}
Ed25519 v = new Ed25519(x, y);
- if (!v.isOnCurve()) {
- throw new AssertionError("not on curve");
- }
return v;
}
@@ -172,6 +171,10 @@
return new Ed25519(x3.mod(q), y3.mod(q));
}
+ public boolean isIdentity() {
+ return P0.mod(q).equals(BigInteger.ZERO) &&
P1.mod(q).equals(BigInteger.ONE);
+ }
+
/**
* Multiply this point by a scalar value.
*
@@ -234,10 +237,7 @@
*/
public byte[] encode() {
byte[] out = encodeScalar(P1);
- System.out.println("encodeScalar " + P1);
- System.out.println("out1 " + Arrays.toString(out));
out[out.length-1] |= (P0.testBit(0) ? (byte) 0x80 : 0);
- System.out.println("out2 " + Arrays.toString(out));
return out;
}
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -36,7 +36,6 @@
return sign(getPublicKey(), purpose, m);
}
-
/**
* Sign the given data with this private key. Must include a purpose to
mitigate
* replay / copy and paste attacks.
@@ -124,15 +123,7 @@
public EddsaPublicKey getPublicKey() {
BigInteger a = computePublicKeyCoefficient();
Ed25519 A = Ed25519.B.scalarmult(a);
- if (!A.isOnCurve()) {
- throw new AssertionError();
- }
- EddsaPublicKey publicKey = new EddsaPublicKey(A);
-
- if (!A.equals(publicKey.asPoint())) {
- throw new AssertionError();
- }
- return publicKey;
+ return new EddsaPublicKey(A);
}
/**
Modified: gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaSignature.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaSignature.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/util/crypto/EddsaSignature.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -54,8 +54,18 @@
this.s = Ed25519.encodeScalar(s);
}
+ /**
+ * Verify the signature on a message with given purpose.
+ *
+ * @param m
+ * @param purpose
+ * @param publicKey
+ * @return
+ */
public boolean verify(byte[] m, int purpose, EddsaPublicKey publicKey) {
Ed25519 R = Ed25519.decode(r);
+ if (!R.isOnCurve())
+ return false;
Ed25519 A = publicKey.asPoint();
BigInteger S = Ed25519.decodeScalar(s);
ByteBuffer Stemp = ByteBuffer.allocate(32 + 32 + m.length);
Modified: gnunet-java/src/main/java/org/gnunet/voting/BallotTool.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/voting/BallotTool.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/voting/BallotTool.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -332,7 +332,7 @@
return;
}
ballotFilename = unprocessedArgs[0];
- if (template) {
+ if (template) {
runTemplate();
return;
}
Modified: gnunet-java/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java
===================================================================
--- gnunet-java/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -126,8 +126,7 @@
}
@Override
public void run(Scheduler.RunContext ctx) {
-
electionState.consensus.conclude(electionState.ballot.concludeTime.getRemaining(),
- new ElectionConsensusConclude(electionState));
+ electionState.consensus.conclude(new
ElectionConsensusConclude(electionState));
}
}
@@ -207,7 +206,9 @@
ids = b.getAuthorities().toArray(ids);
electionState.consensus = new Consensus(getConfiguration(),
ids,
- b.getBallotGuid());
+ b.getBallotGuid(),
+ electionState.ballot.closingTime,
+ electionState.ballot.concludeTime);
ConsensusConcludeTask t = new ConsensusConcludeTask(electionState);
if (b.concludeTime.isDue()) {
Modified: gnunet-java/src/main/resources/org/gnunet/construct/MsgMap.txt
===================================================================
--- gnunet-java/src/main/resources/org/gnunet/construct/MsgMap.txt
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/main/resources/org/gnunet/construct/MsgMap.txt
2014-02-03 23:03:52 UTC (rev 32181)
@@ -41,6 +41,10 @@
org.gnunet.util.GnunetMessage$Body|520=org.gnunet.consensus.messages.JoinMessage
org.gnunet.util.GnunetMessage$Body|521=org.gnunet.consensus.messages.InsertElementMessage
org.gnunet.util.GnunetMessage$Body|523=org.gnunet.consensus.messages.NewElementMessage
+org.gnunet.util.GnunetMessage$Body|782=org.gnunet.secretsharing.messages.DecryptDoneMessage
+org.gnunet.util.GnunetMessage$Body|783=org.gnunet.secretsharing.messages.SecretReadyMessage
+org.gnunet.util.GnunetMessage$Body|780=org.gnunet.secretsharing.messages.GenerateMessage
+org.gnunet.util.GnunetMessage$Body|781=org.gnunet.secretsharing.messages.ClientDecryptMessage
org.gnunet.util.GnunetMessage$Body|68=org.gnunet.core.DisconnectNotifyMessage
org.gnunet.util.GnunetMessage$Body|70=org.gnunet.core.NotifyInboundTrafficMessage
org.gnunet.util.GnunetMessage$Body|476=org.gnunet.testbed.messages.PeerGetInformationMessage
@@ -81,6 +85,8 @@
org.gnunet.util.GnunetMessage$Body|369=org.gnunet.transport.messages.BlacklistInitMessage
org.gnunet.util.GnunetMessage$Body|371=org.gnunet.transport.messages.BlacklistReplyMessage
org.gnunet.util.GnunetMessage$Body|370=org.gnunet.transport.messages.BlacklistQueryMessage
+org.gnunet.util.GnunetMessage$Body|500=org.gnunet.gns.messages.ClientLookupMessage
+org.gnunet.util.GnunetMessage$Body|501=org.gnunet.gns.messages.ClientLookupResultMessage
org.gnunet.util.GnunetMessage$Body|380=org.gnunet.transport.messages.AddressIterateMessage
org.gnunet.util.GnunetMessage$Body|383=org.gnunet.transport.messages.AddressIterateResponseMessage
org.gnunet.util.GnunetMessage$Body|496=org.gnunet.testbed.messages.HelperReplyMessage
@@ -88,4 +94,6 @@
org.gnunet.util.GnunetMessage$Body|366=org.gnunet.transport.messages.SetQuotaMessage
org.gnunet.util.GnunetMessage$Body|360=org.gnunet.transport.messages.StartMessage
org.gnunet.util.GnunetMessage$Body|483=org.gnunet.testbed.messages.ManagePeerServiceMessage
-# generated 2013/10/22 01:57:19
+org.gnunet.gns.records.RecordData|65536=org.gnunet.gns.records.PkeyRecordData
+org.gnunet.gns.records.RecordData|1=org.gnunet.gns.records.ARecordData
+# generated 2014/02/03 23:33:43
Modified:
gnunet-java/src/test/java/org/gnunet/consensus/ConsensusSingleTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/consensus/ConsensusSingleTest.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/consensus/ConsensusSingleTest.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -20,6 +20,7 @@
package org.gnunet.consensus;
+import org.gnunet.testing.TestingFixture;
import org.gnunet.testing.TestingSubsystem;
import org.gnunet.util.*;
import org.junit.Assert;
@@ -31,7 +32,7 @@
/**
* Test consensus with only one peer.
*/
-public class ConsensusSingleTest {
+public class ConsensusSingleTest extends TestingFixture {
@Test
public void test_consensus_single() {
Configuration armConf = new Configuration();
@@ -41,8 +42,12 @@
TestingSubsystem ts = new TestingSubsystem("arm",
armConf.writeTemp().getAbsolutePath());
final Wrapper<Boolean> isDone = new Wrapper<Boolean>(false);
- final Consensus consensus = new Consensus(ts.getConfiguration(), new
PeerIdentity[0],
- HashCode.random());
+ final Consensus consensus = new Consensus(
+ ts.getConfiguration(),
+ new PeerIdentity[0],
+ HashCode.random(),
+ AbsoluteTime.now(),
+ AbsoluteTime.now().add(RelativeTime.SECOND.multiply(10)));
consensus.insertElement(new ConsensusElement("foo".getBytes(), 0));
consensus.insertElement(new ConsensusElement("bar".getBytes(), 0));
@@ -50,7 +55,7 @@
final List<String> received = new LinkedList<String>();
- consensus.conclude(RelativeTime.SECOND, new ConsensusCallback() {
+ consensus.conclude(new ConsensusCallback() {
@Override
public void onElement(ConsensusElement element) {
Assert.assertNotNull(element);
Modified:
gnunet-java/src/test/java/org/gnunet/consensus/ConsensusTestbedTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/consensus/ConsensusTestbedTest.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/consensus/ConsensusTestbedTest.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -5,6 +5,7 @@
import org.gnunet.testbed.Host;
import org.gnunet.testbed.SimpleTestbed;
import org.gnunet.testbed.callbacks.*;
+import org.gnunet.testing.TestingFixture;
import org.gnunet.util.*;
import org.junit.Assert;
import org.junit.Test;
@@ -15,7 +16,7 @@
/**
* Test for consensus with multiple peers using testbed.
*/
-public class ConsensusTestbedTest {
+public class ConsensusTestbedTest extends TestingFixture {
@Test
public void test_consensus_testbed_2peers() {
final Wrapper<Boolean> done = new Wrapper<Boolean>(false);
@@ -33,6 +34,8 @@
int peersStarted;
int peersConcludeDone;
HashCode sessionId = HashCode.random();
+ AbsoluteTime start;
+ AbsoluteTime deadline;
class MyConsensusCallback implements ConsensusCallback {
int n;
@@ -69,11 +72,11 @@
@Override
public void onConnect(Configuration cfg) {
System.out.println("connecting to consensus");
- consensi[n] = new Consensus(cfg, identities, sessionId);
+ consensi[n] = new Consensus(cfg, identities, sessionId,
start, deadline);
consensi[n].insertElement(new
ConsensusElement("foo".getBytes(), 0));
consensi[n].insertElement(new
ConsensusElement("bar".getBytes(), 0));
consensi[n].insertElement(new ConsensusElement(("num" +
n).getBytes(), 0));
- consensi[n].conclude(RelativeTime.SECOND.multiply(10), new
MyConsensusCallback(n));
+ consensi[n].conclude(new MyConsensusCallback(n));
}
@Override
@@ -152,6 +155,8 @@
@Override
public void run() {
+ start = AbsoluteTime.now();
+ deadline = start.add(RelativeTime.SECOND.multiply(10));
// use local peer's config, does that really make sense?
h = new Host(null, null, getConfiguration(), 0);
cp = new ControllerProc();
Modified: gnunet-java/src/test/java/org/gnunet/core/CoreTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/core/CoreTest.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/core/CoreTest.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -77,6 +77,7 @@
final Core core = new Core(ts.getConfiguration());
core.setMessageHandler(new Runabout() {
public void visit(TestMessage t) {
+ System.out.println("got core response");
gotResponse.set(true);
core.disconnect();
}
@@ -85,7 +86,8 @@
core.init(new InitCallback() {
@Override
public void onInit(PeerIdentity myIdentity) {
- System.out.println("in core init");
+ System.out.println("in core init, my identity is " +
myIdentity);
+ // we want to send a 4-byte TestMessage
core.notifyTransmitReady(0, RelativeTime.FOREVER, myIdentity,
4, new MessageTransmitter() {
@Override
public void transmit(Connection.MessageSink sink) {
Modified: gnunet-java/src/test/java/org/gnunet/identity/IdentityTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/identity/IdentityTest.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/identity/IdentityTest.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -21,6 +21,7 @@
package org.gnunet.identity;
+import org.gnunet.testing.TestingFixture;
import org.gnunet.testing.TestingSubsystem;
import org.gnunet.util.Program;
import org.gnunet.util.Scheduler;
@@ -28,7 +29,7 @@
import org.junit.Assert;
import org.junit.Test;
-public class IdentityTest {
+public class IdentityTest extends TestingFixture {
@Test
public void test_identity_connect() {
final Wrapper<Boolean> reachedEnd = new Wrapper<Boolean>(false);
Modified: gnunet-java/src/test/java/org/gnunet/transport/TransportTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/transport/TransportTest.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/transport/TransportTest.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -23,6 +23,7 @@
import org.gnunet.hello.HelloMessage;
import org.gnunet.peerinfo.PeerInfo;
import org.gnunet.peerinfo.PeerProcessor;
+import org.gnunet.testing.TestingFixture;
import org.gnunet.testing.TestingSubsystem;
import org.gnunet.transport.callbacks.HelloUpdateCallback;
import org.gnunet.util.*;
@@ -30,8 +31,8 @@
import static org.junit.Assert.assertTrue;
-public class TransportTest {
- @Test
+public class TransportTest extends TestingFixture {
+ @Test(timeout = 5000)
public void test_transport_get_hello() {
Program.configureLogging("debug");
final Wrapper<Boolean> ended = new Wrapper<Boolean>(false);
Modified: gnunet-java/src/test/java/org/gnunet/util/ClientServerTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/util/ClientServerTest.java
2014-02-03 23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/util/ClientServerTest.java
2014-02-03 23:03:52 UTC (rev 32181)
@@ -3,6 +3,7 @@
import com.google.common.collect.Lists;
import org.gnunet.construct.UInt32;
import org.gnunet.construct.UnionCase;
+import org.gnunet.testing.TestingFixture;
import org.gnunet.testing.TestingServer;
import org.gnunet.testing.TestingSetup;
import org.junit.Assert;
@@ -20,7 +21,7 @@
*
* @author Florian Dold
*/
-public class ClientServerTest {
+public class ClientServerTest extends TestingFixture {
@Test
public void test_start_stop() {
Modified: gnunet-java/src/test/java/org/gnunet/util/EcdheTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/util/EcdheTest.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/util/EcdheTest.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -74,13 +74,29 @@
privKey1.d = new byte[32];
EcdhePrivateKey privKey2 = new EcdhePrivateKey();
privKey2.d = new byte[32];
-
Strings.stringToData("FH7DONLOP82RMELK26NDEP8655HQFU9LUO36LNO1ENOJ5KOSRR00",
privKey1.d);
-
Strings.stringToData("LAJES5PBR68MJQP067I7DLJO3RUGG0EUHSOAVOFIDF24KBDE0SEG",
privKey2.d);
+
Strings.stringToData("A46TL3L8CF7R3BPPQDE8LJS999NQ58HD43DV11MPFI2B5JNJMM40",
privKey1.d);
+
Strings.stringToData("B60MFOBFKCVT0IVFDI800MH345FG372UJ4T7GEMNMO72O64G0D00",
privKey2.d);
EcdhePublicKey pubKey1 = privKey1.getPublicKey();
EcdhePublicKey pubKey2 = privKey2.getPublicKey();
-
Assert.assertEquals("VU5U4KNC3OH5RUL6M5T6BPH52BFBICEG5Q60A43V97HQV1VD3AG0",
pubKey1.toString());
-
Assert.assertEquals("8DSB6D0OKS1SD71BKRTVT8OK18Q73Q7MUALJ76V9DQJO6J0170RG",
pubKey2.toString());
+
Assert.assertEquals("JLU00RUGNB04APG6I9RKVT1CJLB16U8T7G130CC2IV4O3LJG5K40",
pubKey1.toString());
+
+
Assert.assertEquals("G9TDOQVP3CFA2K5Q7PSS8Q935FVEHAF3C08JPV1H3MPDK1ESLM6G",
pubKey2.toString());
+
+ HashCode h1 = privKey1.ecdh(pubKey2);
+ HashCode h2 = privKey2.ecdh(pubKey1);
+
+ Assert.assertEquals(h1, h2);
+
+ byte[] gnunet_data = new byte[64];
+ boolean success = Strings.stringToData(
+ "R9A80A2VU4R0IL3NT4FBIMFRCGVP72DQODHTQQ1SGR65I4PMF1" +
+ "6C3ELIF2RSB9L8H0KLOUU795IM5L0CLCISI607B5P1QE8HRAPA56O",
+ gnunet_data);
+ Assert.assertTrue(success);
+
+ Assert.assertArrayEquals(gnunet_data, h1.data);
+
}
}
Modified: gnunet-java/src/test/java/org/gnunet/util/EcdsaTest.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/util/EcdsaTest.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/util/EcdsaTest.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -24,13 +24,21 @@
import org.junit.Assert;
import org.junit.Test;
+import java.math.BigInteger;
+
public class EcdsaTest {
@Test
public void test_sign_success() {
byte[] data = "GNUnet".getBytes();
- EcdsaPrivateKey privateKey = EcdsaPrivateKey.createRandom();
+ //EcdsaPrivateKey privateKey = EcdsaPrivateKey.createRandom();
+ EcdsaPrivateKey privateKey = new EcdsaPrivateKey();
+ privateKey.d = Ed25519.encodeScalar(new
BigInteger("9751885127070397687372377515580876465521419304255864589795046632195735740054"));
EcdsaPublicKey publicKey = privateKey.getPublicKey();
EcdsaSignature signature = privateKey.sign(publicKey, 0, data);
+ System.out.println("private key: " +
Ed25519.decodeScalar(privateKey.d));
+ System.out.println("public key: " + publicKey.asPoint());
+ System.out.println("signature r: " +
Ed25519.decodeScalar(signature.r));
+ System.out.println("signature s: " +
Ed25519.decodeScalar(signature.s));
Assert.assertTrue(signature.verify(data, 0, publicKey));
}
Modified: gnunet-java/src/test/java/org/gnunet/util/Ed25519Test.java
===================================================================
--- gnunet-java/src/test/java/org/gnunet/util/Ed25519Test.java 2014-02-03
23:00:30 UTC (rev 32180)
+++ gnunet-java/src/test/java/org/gnunet/util/Ed25519Test.java 2014-02-03
23:03:52 UTC (rev 32181)
@@ -46,7 +46,7 @@
/**
* Raw ECDH check.
*/
- //@Test
+ @Test
public void test_ecdh() {
for (int i = 0; i < 5; ++i) {
System.out.println("try " + i);
@@ -92,10 +92,10 @@
/**
* Test if decode is the inverse of encode.
*/
- //@Test
+ @Test
public void test_encode_inverse() {
Random r = new Random();
- for (int i = 0; i < 100; i++) {
+ for (int i = 0; i < 5; i++) {
byte[] d1 = new byte[32];
r.nextBytes(d1);
d1[31] &= 127;
@@ -139,4 +139,11 @@
Assert.assertArrayEquals(d1, d2);
}
}
+
+ @Test
+ public void test_order() {
+ Ed25519 P = Ed25519.B.scalarmult(Ed25519.l);
+ System.out.println("Point P: " + P);
+ Assert.assertTrue(P.isIdentity());
+ }
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r32181 - in gnunet-java: . bin src/main/java/org/gnunet/consensus src/main/java/org/gnunet/consensus/messages src/main/java/org/gnunet/construct src/main/java/org/gnunet/core src/main/java/org/gnunet/gns src/main/java/org/gnunet/gns/messages src/main/java/org/gnunet/identity src/main/java/org/gnunet/peerinfo src/main/java/org/gnunet/testing src/main/java/org/gnunet/transport src/main/java/org/gnunet/transport/messages src/main/java/org/gnunet/util src/main/java/org/gnunet/util/crypto src/main/java/org/gnunet/voting src/main/resources/org/gnunet/construct src/test/java/org/gnunet/consensus src/test/java/org/gnunet/core src/test/java/org/gnunet/identity src/test/java/org/gnunet/transport src/test/java/org/gnunet/util,
gnunet <=