[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r18983 - in gnunet-java: . src/org/gnunet/construct src/org
From: |
gnunet |
Subject: |
[GNUnet-SVN] r18983 - in gnunet-java: . src/org/gnunet/construct src/org/gnunet/service src/org/gnunet/util test/org/gnunet/services |
Date: |
Wed, 4 Jan 2012 15:37:11 +0100 |
Author: dold
Date: 2012-01-04 15:37:11 +0100 (Wed, 04 Jan 2012)
New Revision: 18983
Added:
gnunet-java/src/org/gnunet/service/NSE_StartMessage.java
gnunet-java/src/org/gnunet/service/NSE_UpdateMessage.java
Modified:
gnunet-java/ISSUES
gnunet-java/src/org/gnunet/construct/Construct.java
gnunet-java/src/org/gnunet/construct/MessageIdAnnotationProcessor.java
gnunet-java/src/org/gnunet/construct/MessageLoader.java
gnunet-java/src/org/gnunet/construct/MsgMap.txt
gnunet-java/src/org/gnunet/service/NetworkSizeEstimationService.java
gnunet-java/src/org/gnunet/util/AbsoluteTimeMessage.java
gnunet-java/src/org/gnunet/util/Client.java
gnunet-java/src/org/gnunet/util/RelativeTime.java
gnunet-java/src/org/gnunet/util/RelativeTimeMessage.java
gnunet-java/src/org/gnunet/util/Scheduler.java
gnunet-java/test/org/gnunet/services/NetworkSizeEstimationServiceTest.java
Log:
added MsgMap update shell script
Modified: gnunet-java/ISSUES
===================================================================
--- gnunet-java/ISSUES 2012-01-04 14:20:36 UTC (rev 18982)
+++ gnunet-java/ISSUES 2012-01-04 14:37:11 UTC (rev 18983)
@@ -112,16 +112,20 @@
=====
- * what about unifying the many types of callbacks?
- * what about async versions of some api calls? (e.g. for usage in a repl)
+* how do we handle RelativeTime(0) timeouts?
-
* header redundant -> introduce NetworkMessage with header automatically
prepended?
+ * static distinction between Messages with and without header
* support for minimum message size in construct?
- * generic support for subscriptions
+
* buffering scheme / when is "enough space" in a buffer?
- * where to put messages in a buffer? at the beginning? at (capacity - size)?
\ No newline at end of file
+ * where to put messages in a buffer? at the beginning? at (capacity - size)?
+
+
+ * what about unifying the many types of callbacks?
+ * what about async versions of some api calls? (e.g. for usage in a repl)
+* generic support for subscriptions
\ No newline at end of file
Modified: gnunet-java/src/org/gnunet/construct/Construct.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Construct.java 2012-01-04 14:20:36 UTC
(rev 18982)
+++ gnunet-java/src/org/gnunet/construct/Construct.java 2012-01-04 14:37:11 UTC
(rev 18983)
@@ -42,7 +42,7 @@
throw new InterfaceViolationException("Cannot instantiate
Message");
} catch (IllegalAccessException e) {
throw new InterfaceViolationException(
- "Cannot instantiate Message (illegal access)");
+ String.format("Cannot instantiate Message %s (illegal
access)", c));
}
getParser(c).parse(data, offset, 0, m);
Modified: gnunet-java/src/org/gnunet/construct/MessageIdAnnotationProcessor.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/MessageIdAnnotationProcessor.java
2012-01-04 14:20:36 UTC (rev 18982)
+++ gnunet-java/src/org/gnunet/construct/MessageIdAnnotationProcessor.java
2012-01-04 14:37:11 UTC (rev 18983)
@@ -50,7 +50,7 @@
DateFormat fmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
- w.write("# generated " + fmt.format(new Date()));
+ w.write("# generated " + fmt.format(new Date()) + "\n");
w.close();
} catch (IOException e) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not
write MsgMap.txt");
@@ -59,7 +59,7 @@
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
"message map written to " + outfile.toUri());
} else {
- for (Element e : roundEnvironment.getRootElements()) {
+ for (Element e :
roundEnvironment.getElementsAnnotatedWith(MessageId.class)) {
Annotation ann = e.getAnnotation(MessageId.class);
if (ann != null) {
int id = ((MessageId)
e.getAnnotation(MessageId.class)).value();
Modified: gnunet-java/src/org/gnunet/construct/MessageLoader.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/MessageLoader.java 2012-01-04
14:20:36 UTC (rev 18982)
+++ gnunet-java/src/org/gnunet/construct/MessageLoader.java 2012-01-04
14:37:11 UTC (rev 18983)
@@ -37,6 +37,10 @@
public class MessageLoader {
private static HashMap<java.lang.Integer, String> msgmap = new
HashMap<Integer, String>();
+ static {
+ loadMessageMap();
+ }
+
public static void loadMessageMap() {
URL loc = MessageLoader.class.getResource("MsgMap.txt");
if (loc == null) {
@@ -75,12 +79,12 @@
throw new MessageFormatException("don't know how to translate
message of type " + type);
}
- ClassLoader cl = MessageLoader.class.getClassLoader();
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
Class msgClass;
try {
msgClass = cl.loadClass(className);
} catch (ClassNotFoundException e) {
- throw new InternalLogicError("message class not found in
classpath");
+ throw new InternalLogicError(String.format("message class '%s' not
found in classpath", className));
}
return Construct.parseAs(data, offset, msgClass);
Modified: gnunet-java/src/org/gnunet/construct/MsgMap.txt
===================================================================
--- gnunet-java/src/org/gnunet/construct/MsgMap.txt 2012-01-04 14:20:36 UTC
(rev 18982)
+++ gnunet-java/src/org/gnunet/construct/MsgMap.txt 2012-01-04 14:37:11 UTC
(rev 18983)
@@ -1,6 +1,6 @@
987=org.gnunet.construct.SizeTestMessage
291=org.gnunet.construct.QueryMessage
-323=org.gnunet.service.NSE_Update
-321=org.gnunet.service.NSE_Start
+323=org.gnunet.service.NSE_UpdateMessage
+321=org.gnunet.service.NSE_StartMessage
3210=org.gnunet.construct.SimpleTestMessage
-# generated 2012/01/03 01:07:59
\ No newline at end of file
+# generated 2012/01/04 12:40:14
Added: gnunet-java/src/org/gnunet/service/NSE_StartMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/service/NSE_StartMessage.java
(rev 0)
+++ gnunet-java/src/org/gnunet/service/NSE_StartMessage.java 2012-01-04
14:37:11 UTC (rev 18983)
@@ -0,0 +1,15 @@
+package org.gnunet.service;
+
+import org.gnunet.construct.Message;
+import org.gnunet.construct.MessageHeader;
+import org.gnunet.construct.MessageId;
+import org.gnunet.construct.Nested;
+
address@hidden("InstanceVariableMayNotBeInitialized")
address@hidden(NSE_StartMessage.MSG_ID)
+public class NSE_StartMessage implements Message {
+ public static final int MSG_ID = 321;
+
+ @Nested
+ public MessageHeader header;
+}
Added: gnunet-java/src/org/gnunet/service/NSE_UpdateMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/service/NSE_UpdateMessage.java
(rev 0)
+++ gnunet-java/src/org/gnunet/service/NSE_UpdateMessage.java 2012-01-04
14:37:11 UTC (rev 18983)
@@ -0,0 +1,27 @@
+package org.gnunet.service;
+
+import org.gnunet.construct.*;
+import org.gnunet.construct.Double;
+import org.gnunet.util.AbsoluteTimeMessage;
+
address@hidden("InstanceVariableMayNotBeInitialized")
address@hidden(NSE_UpdateMessage.MSG_ID)
+public class NSE_UpdateMessage implements Message {
+ public static final int MSG_ID = 323;
+
+ @Nested
+ public MessageHeader header;
+
+ @UInt32
+ public int reserved;
+
+ @Nested
+ public AbsoluteTimeMessage timestamp;
+
+ @Double
+ public double sizeEstimate;
+
+ @Double
+ public double stdDeviation;
+
+}
\ No newline at end of file
Modified: gnunet-java/src/org/gnunet/service/NetworkSizeEstimationService.java
===================================================================
--- gnunet-java/src/org/gnunet/service/NetworkSizeEstimationService.java
2012-01-04 14:20:36 UTC (rev 18982)
+++ gnunet-java/src/org/gnunet/service/NetworkSizeEstimationService.java
2012-01-04 14:37:11 UTC (rev 18983)
@@ -1,62 +1,36 @@
package org.gnunet.service;
-import org.gnunet.construct.*;
-import org.gnunet.construct.Double;
+import org.gnunet.construct.Message;
+import org.gnunet.construct.MessageHeader;
import org.gnunet.exceptions.MessageFormatException;
import org.gnunet.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.HashSet;
+import java.util.Set;
-
-
-
public class NetworkSizeEstimationService {
- @SuppressWarnings("InstanceVariableMayNotBeInitialized")
- @MessageId(NSE_Start.MSG_ID)
- public static class NSE_Start implements Message {
- public static final int MSG_ID = 321;
- @Nested
- public MessageHeader header;
- }
-
- @SuppressWarnings("InstanceVariableMayNotBeInitialized")
- @MessageId(NSE_Update.MSG_ID)
- public static class NSE_Update implements Message {
- public static final int MSG_ID = 323;
-
- @Nested
- public MessageHeader header;
-
- @UInt32
- public int reserved;
-
- @Nested
- public AbsoluteTimeMessage timestamp;
-
- @Double
- public double sizeEstimate;
-
- @Double
- public double stdDeviation;
- }
-
-
private static final Logger logger = LoggerFactory
.getLogger(NetworkSizeEstimationService.class);
+
+ Set<NSE_Subscriber> subscribers = new HashSet<NSE_Subscriber>();
class NSE_Receiver implements MessageReceiver {
-
@Override
public void process(Message msg) {
- if (!(msg instanceof NSE_Update)) {
+ if (!(msg instanceof NSE_UpdateMessage)) {
throw new MessageFormatException("got unexcpected message");
}
+ NSE_UpdateMessage uMsg = (NSE_UpdateMessage) msg;
System.out.println("got message back!");
+ for (NSE_Subscriber s : subscribers) {
+ s.update(null, uMsg.sizeEstimate, uMsg.stdDeviation);
+ }
}
@Override
@@ -71,9 +45,9 @@
@Override
public void transmit(Client.MessageSink sink) {
logger.debug("ready to transmit");
- NSE_Start m = new NSE_Start();
+ NSE_StartMessage m = new NSE_StartMessage();
m.header = new MessageHeader();
- m.header.messageType = NSE_Start.MSG_ID;
+ m.header.messageType = NSE_StartMessage.MSG_ID;
m.header.messageSize = MessageHeader.SIZE;
sink.send(m);
@@ -89,15 +63,23 @@
}
public class NSE_Subscription {
-
+ private NSE_Subscriber sub;
+ private NSE_Subscription(NSE_Subscriber sub) {
+ this.sub = sub;
+ }
+ public void cancel() {
+ subscribers.remove(sub);
+ }
}
public interface NSE_Subscriber {
+ public void update(AbsoluteTime timestamp, double estimate, double
deviation);
}
public NSE_Subscription subscribe(NSE_Subscriber s) {
- return null;
+ subscribers.add(s);
+ return new NSE_Subscription(s);
}
Client client;
Modified: gnunet-java/src/org/gnunet/util/AbsoluteTimeMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/util/AbsoluteTimeMessage.java 2012-01-04
14:20:36 UTC (rev 18982)
+++ gnunet-java/src/org/gnunet/util/AbsoluteTimeMessage.java 2012-01-04
14:37:11 UTC (rev 18983)
@@ -1,7 +1,10 @@
package org.gnunet.util;
import org.gnunet.construct.Message;
+import org.gnunet.construct.UInt64;
public class AbsoluteTimeMessage implements Message {
+ @UInt64
+ public long __value;
}
Modified: gnunet-java/src/org/gnunet/util/Client.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Client.java 2012-01-04 14:20:36 UTC (rev
18982)
+++ gnunet-java/src/org/gnunet/util/Client.java 2012-01-04 14:37:11 UTC (rev
18983)
@@ -20,17 +20,18 @@
package org.gnunet.util;
import org.gnunet.construct.Construct;
-import org.gnunet.exceptions.ConfigurationException;
-import org.gnunet.exceptions.InterfaceViolationException;
import org.gnunet.construct.Message;
import org.gnunet.construct.MessageHeader;
import org.gnunet.construct.MessageLoader;
+import org.gnunet.exceptions.ConfigurationException;
+import org.gnunet.exceptions.InterfaceViolationException;
import org.gnunet.util.Scheduler.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOError;
import java.io.IOException;
+import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
@@ -53,11 +54,12 @@
private ByteBuffer recvBuffer = ByteBuffer.allocate(INITIAL_BUFFER_SIZE);
- private TransmitHelperTask currentTransmit = null;
+ private TransmitHelper currentTransmit = null;
private Scheduler.TaskIdentifier nextTransmitTimeout = null;
private ByteBuffer transmitBuffer =
ByteBuffer.allocate(INITIAL_BUFFER_SIZE);
private MessageTransmitter nextTransmitter;
+ private boolean connected;
public class TransmitHandle {
/**
@@ -73,14 +75,14 @@
public void send(Message m);
}
- private class ReceiveHelperTask implements Task {
+ private class ReceiveHelper implements Task {
private MessageReceiver receiver;
private RelativeTime timeout;
private boolean headerProcessed = false;
private MessageHeader msgh;
- public ReceiveHelperTask(MessageReceiver receiver, RelativeTime
timeout) {
+ public ReceiveHelper(MessageReceiver receiver, RelativeTime timeout) {
this.receiver = receiver;
this.timeout = timeout;
recvActive = true;
@@ -134,10 +136,10 @@
}
- private class TransmitHelperTask implements Task, MessageSink {
+ private class TransmitHelper implements Task, MessageSink {
private MessageTransmitter transmitter;
- public TransmitHelperTask(MessageTransmitter transmitter) {
+ public TransmitHelper(MessageTransmitter transmitter) {
this.transmitter = transmitter;
}
@@ -153,7 +155,7 @@
}
if (transmitBuffer.remaining() == 0) {
logger.debug("done transmitting " + transmitBuffer.position());
- if (nextTransmitTimeout == null) {
+ if (nextTransmitter == null) {
currentTransmit = null;
} else {
transmitBuffer.clear();
@@ -186,8 +188,7 @@
}
}
-
- public class ConnectTask implements Task {
+ public class ConnectHelper implements Task {
@Override
public void run(Context ctx) {
tryConnect();
@@ -195,13 +196,21 @@
public void tryConnect() {
try {
- boolean connected = chan.finishConnect();
- if (!connected) {
+ if (chan.finishConnect()) {
+ logger.debug("finished connect");
+ connected = true;
+ if (currentTransmit == null && nextTransmitter != null) {
+ MessageTransmitter t = nextTransmitter;
+ nextTransmitter = null;
+ startTransmit(nextTransmitter);
+ }
+ } else {
logger.debug("still not finished");
Scheduler.addDelayed(new RelativeTime(5), this);
- } else {
- logger.debug("finished connect");
}
+ } catch (ConnectException e) {
+ logger.debug("got connect exception");
+ Scheduler.addDelayed(new RelativeTime(5), this);
} catch (IOException e) {
throw new IOError(e);
}
@@ -209,6 +218,7 @@
}
+
/**
* Get a connection with a service.
*
@@ -230,17 +240,12 @@
throw new IOError(e);
}
try {
- boolean ret = chan.connect(new InetSocketAddress(hostname, port));
- if (ret) {
- logger.debug("connection established right now");
- } else {
- logger.debug("must wait for connect to finish");
- }
+ chan.connect(new InetSocketAddress(hostname, port));
} catch (IOException e) {
// todo: retry until connect possible
throw new IOError(e);
}
- ConnectTask ct = new ConnectTask();
+ ConnectHelper ct = new ConnectHelper();
ct.tryConnect();
}
@@ -275,7 +280,7 @@
logger.debug("receive requested");
recvBuffer.clear();
recvBuffer.limit(MessageHeader.SIZE);
- ReceiveHelperTask rh = new ReceiveHelperTask(receiver, timeout);
+ ReceiveHelper rh = new ReceiveHelper(receiver, timeout);
rh.schedule();
}
@@ -295,29 +300,34 @@
}
}
+
+ private void startTransmit(MessageTransmitter transmitter) {
+ // we can just begin transmitting
+ TransmitHelper transmitHelper = new TransmitHelper(transmitter);
+ transmitBuffer.clear();
+ transmitter.transmit(transmitHelper);
+ transmitBuffer.flip();
+ transmitHelper.schedule();
+ currentTransmit = transmitHelper;
+ }
public TransmitHandle notifyTransmitReady(int size, RelativeTime timeout,
boolean autoRetry,
MessageTransmitter transmitter) {
- if (nextTransmitTimeout != null) {
+ if (nextTransmitter != null) {
throw new InterfaceViolationException(
"previous transmit request must have completed before
calling notifyTransmitReady again");
}
if (size > transmitBuffer.capacity()) {
throw new RuntimeException("buffer size too small");
}
- if (currentTransmit == null) {
- // we can just begin transmitting
- TransmitHelperTask task = new TransmitHelperTask(transmitter);
- transmitBuffer.clear();
- transmitter.transmit(task);
- logger.debug("AFTER: " + transmitBuffer.position());
- transmitBuffer.flip();
- task.schedule();
- currentTransmit = task;
+ if (currentTransmit == null && connected) {
+ startTransmit(transmitter);
} else {
- TransmitTimeoutHelper h = new TransmitTimeoutHelper(transmitter,
size);
- nextTransmitTimeout = Scheduler.addDelayed(timeout, h);
+ if (!timeout.isForever()) {
+ TransmitTimeoutHelper h = new
TransmitTimeoutHelper(transmitter, size);
+ nextTransmitTimeout = Scheduler.addDelayed(timeout, h);
+ }
nextTransmitter = transmitter;
}
return new TransmitHandle();
Modified: gnunet-java/src/org/gnunet/util/RelativeTime.java
===================================================================
--- gnunet-java/src/org/gnunet/util/RelativeTime.java 2012-01-04 14:20:36 UTC
(rev 18982)
+++ gnunet-java/src/org/gnunet/util/RelativeTime.java 2012-01-04 14:37:11 UTC
(rev 18983)
@@ -159,7 +159,11 @@
return AbsoluteTime.now().add(this);
}
+ public boolean isForever() {
+ return rel_value == FOREVER.rel_value;
+ }
+
public RelativeTimeMessage toNBO() {
long rval = this.rel_value;
assert rval >= 0;
Modified: gnunet-java/src/org/gnunet/util/RelativeTimeMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/util/RelativeTimeMessage.java 2012-01-04
14:20:36 UTC (rev 18982)
+++ gnunet-java/src/org/gnunet/util/RelativeTimeMessage.java 2012-01-04
14:37:11 UTC (rev 18983)
@@ -1,7 +1,7 @@
package org.gnunet.util;
import org.gnunet.construct.Message;
-import org.gnunet.construct.UInt8;
+import org.gnunet.construct.UInt64;
public class RelativeTimeMessage implements Message {
@@ -9,7 +9,7 @@
* Value__ still in Java-byte order, needs to be converted to Network byte
* order by the Construct class.
*/
- @UInt8
+ @UInt64
public long value__;
public RelativeTimeMessage(final long value) {
Modified: gnunet-java/src/org/gnunet/util/Scheduler.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Scheduler.java 2012-01-04 14:20:36 UTC
(rev 18982)
+++ gnunet-java/src/org/gnunet/util/Scheduler.java 2012-01-04 14:37:11 UTC
(rev 18983)
@@ -134,6 +134,7 @@
key.interestOps(key.interestOps() | op);
}
}
+
public void register() {
for (SelectableChannel sc : rs) {
@@ -349,19 +350,16 @@
if (ready_count > 0) {
return true;
}
-
for (TaskIdentifier t : pending) {
if (t.liveness) {
return true;
}
}
-
for (TaskIdentifier t : pending_timeout) {
if (t.liveness) {
return true;
}
}
-
// do we have only tasks pending which are not alive?
if (!pending.isEmpty() || !pending_timeout.isEmpty()) {
logger.debug("tasks pending but not alive -- shutdown");
@@ -426,6 +424,15 @@
}
}
+ if (ready_count > 0) {
+ timeout = RelativeTime.ZERO;
+ } else if (!pending_timeout.isEmpty()) {
+ timeout = pending_timeout.element().timeout.getDifference(now);
+ assert timeout.getMilliseconds() > 0;
+ } else {
+ timeout = RelativeTime.FOREVER;
+ }
+
try {
// selector.select(0) would block indefinitely
if (timeout.getMilliseconds() == 0) {
@@ -440,14 +447,13 @@
throw new IOError(e);
}
+ HashSet<TimeoutTask> executableTasks = new HashSet<TimeoutTask>();
for (SelectionKey sk : selector.selectedKeys()) {
Object obj = sk.attachment();
assert (obj instanceof SubscriberSet);
SubscriberSet ss = (SubscriberSet) obj;
-
-
- HashSet<TimeoutTask> executableTasks = new
HashSet<TimeoutTask>();
+
if ((sk.interestOps() & SelectionKey.OP_READ) != 0) {
for (TimeoutTask tt : ss.readers) {
executableTasks.add(tt);
@@ -469,13 +475,12 @@
}
}
}
-
- for (TimeoutTask tt : executableTasks) {
- // tasks must do this themselve to cancel subscriptions to
other channels
- tt.deregister();
- queueReady(tt);
- }
}
+ for (TimeoutTask tt : executableTasks) {
+ // tasks must do this themselve to cancel subscriptions to
other channels
+ tt.deregister();
+ queueReady(tt);
+ }
runReady();
}
Modified:
gnunet-java/test/org/gnunet/services/NetworkSizeEstimationServiceTest.java
===================================================================
--- gnunet-java/test/org/gnunet/services/NetworkSizeEstimationServiceTest.java
2012-01-04 14:20:36 UTC (rev 18982)
+++ gnunet-java/test/org/gnunet/services/NetworkSizeEstimationServiceTest.java
2012-01-04 14:37:11 UTC (rev 18983)
@@ -2,18 +2,22 @@
import org.gnunet.service.NetworkSizeEstimationService;
+import org.gnunet.util.AbsoluteTime;
import org.gnunet.util.Configuration;
import org.gnunet.util.Scheduler;
import org.junit.Test;
import java.io.File;
-public class NetworkSizeEstimationServiceTest {
+public class NetworkSizeEstimationServiceTest{
@Test
public void test_1() {
+
+
File tmpFile = ConfigUtil.copyConfigResource("nse.conf");
+
/*
Process p;
try {
@@ -22,16 +26,25 @@
} catch (IOException e) {
throw new IOError(e);
}
+
*/
Configuration cfg = new Configuration(tmpFile.getAbsolutePath());
NetworkSizeEstimationService svc = new
NetworkSizeEstimationService(cfg);
+ svc.subscribe(new NetworkSizeEstimationService.NSE_Subscriber() {
+ @Override
+ public void update(AbsoluteTime t, double estimate, double
deviation) {
+ System.out.println("------\ngot it\n-------\n");
+ System.out.println("est:" + estimate + " dev: " + deviation);
+ }
+ });
+
System.out.println("starting scheduler");
Scheduler.run(Scheduler.NO_TASK);
- // p.destroy();
+ //p.destroy();
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r18983 - in gnunet-java: . src/org/gnunet/construct src/org/gnunet/service src/org/gnunet/util test/org/gnunet/services,
gnunet <=