aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/gnunet
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2013-09-25 11:32:19 +0000
committerFlorian Dold <florian.dold@gmail.com>2013-09-25 11:32:19 +0000
commitaeeeaff2736808a6eaa2138272c46544676e49f3 (patch)
tree6278c672e4c4563664253683c92cd83cb1e0c636 /src/main/java/org/gnunet
parent67e978773774a0e7ef1f23209b884847837224ad (diff)
downloadgnunet-java-aeeeaff2736808a6eaa2138272c46544676e49f3.tar.gz
gnunet-java-aeeeaff2736808a6eaa2138272c46544676e49f3.zip
- testbed: create/destroy, start/stop, getInformation, connectOverlay implementation and tests
- voting: ballot serialization/deserialization, unencrypted tally authority implementation, ballot tool works for register/vote/query - issues
Diffstat (limited to 'src/main/java/org/gnunet')
-rw-r--r--src/main/java/org/gnunet/consensus/ConcludeCallback.java20
-rw-r--r--src/main/java/org/gnunet/consensus/ConcludeDoneMessage.java20
-rw-r--r--src/main/java/org/gnunet/consensus/ConcludeMessage.java20
-rw-r--r--src/main/java/org/gnunet/consensus/Consensus.java20
-rw-r--r--src/main/java/org/gnunet/consensus/ConsensusElement.java20
-rw-r--r--src/main/java/org/gnunet/consensus/InsertDoneCallback.java20
-rw-r--r--src/main/java/org/gnunet/consensus/InsertElementMessage.java20
-rw-r--r--src/main/java/org/gnunet/consensus/NewElementCallback.java20
-rw-r--r--src/main/java/org/gnunet/consensus/NewElementMessage.java20
-rw-r--r--src/main/java/org/gnunet/mesh/Mesh.java69
-rw-r--r--src/main/java/org/gnunet/mesh/MeshRunabout.java6
-rw-r--r--src/main/java/org/gnunet/mesh/TunnelEndHandler.java7
-rw-r--r--src/main/java/org/gnunet/requests/MatchingRequestContainer.java14
-rw-r--r--src/main/java/org/gnunet/testbed/CompressedConfig.java19
-rw-r--r--src/main/java/org/gnunet/testbed/Controller.java392
-rw-r--r--src/main/java/org/gnunet/testbed/Operation.java11
-rw-r--r--src/main/java/org/gnunet/testbed/callbacks/OperationCompletionCallback.java10
-rw-r--r--src/main/java/org/gnunet/testbed/callbacks/PeerInformationCallback.java29
-rw-r--r--src/main/java/org/gnunet/testbed/callbacks/ServiceAdapter.java28
-rw-r--r--src/main/java/org/gnunet/testbed/messages/ConnectionEventMessage.java52
-rw-r--r--src/main/java/org/gnunet/testbed/messages/ControllerInitMessage.java21
-rw-r--r--src/main/java/org/gnunet/testbed/messages/CreatePeerSuccessMessage.java5
-rw-r--r--src/main/java/org/gnunet/testbed/messages/GenericOperationSuccessMessage.java20
-rw-r--r--src/main/java/org/gnunet/testbed/messages/ManagePeerServiceMessage.java26
-rw-r--r--src/main/java/org/gnunet/testbed/messages/OperationFailEventMessage.java23
-rw-r--r--src/main/java/org/gnunet/testbed/messages/OverlayConnectMessage.java4
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerConfigurationInformationMessage.java8
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerCreateSuccessMessage.java2
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerDestroyMessage.java2
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerEventMessage.java8
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerGetInformationMessage.java34
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java56
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerReconfigureMessage.java15
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerStartMessage.java2
-rw-r--r--src/main/java/org/gnunet/testbed/messages/PeerStopMessage.java2
-rw-r--r--src/main/java/org/gnunet/util/AbsoluteTime.java4
-rw-r--r--src/main/java/org/gnunet/util/CryptoECC.java58
-rw-r--r--src/main/java/org/gnunet/util/HashCode.java5
-rw-r--r--src/main/java/org/gnunet/util/PeerIdentity.java6
-rw-r--r--src/main/java/org/gnunet/util/Program.java10
-rw-r--r--src/main/java/org/gnunet/util/RunaboutMessageReceiver.java9
-rw-r--r--src/main/java/org/gnunet/util/Strings.java10
-rw-r--r--src/main/java/org/gnunet/voting/Ballot.java289
-rw-r--r--src/main/java/org/gnunet/voting/BallotTool.java162
-rw-r--r--src/main/java/org/gnunet/voting/InvalidBallotException.java30
-rw-r--r--src/main/java/org/gnunet/voting/PermissionCommand.java132
-rw-r--r--src/main/java/org/gnunet/voting/QueryCommand.java120
-rw-r--r--src/main/java/org/gnunet/voting/RegisterCommand.java119
-rw-r--r--src/main/java/org/gnunet/voting/SubmitCommand.java84
-rw-r--r--src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java116
-rw-r--r--src/main/java/org/gnunet/voting/TallyAuthorityService.java81
-rw-r--r--src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java5
-rw-r--r--src/main/java/org/gnunet/voting/messages/BallotRegisterRespondMessage.java6
-rw-r--r--src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java6
-rw-r--r--src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java6
-rw-r--r--src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java28
-rw-r--r--src/main/java/org/gnunet/voting/messages/QueryMessage.java12
-rw-r--r--src/main/java/org/gnunet/voting/messages/QueryResponseMessage.java12
-rw-r--r--src/main/java/org/gnunet/voting/messages/QueryResultMessage.java5
-rw-r--r--src/main/java/org/gnunet/voting/messages/QueryResultResponseMessage.java5
-rw-r--r--src/main/java/org/gnunet/voting/messages/SubmitMessage.java11
-rw-r--r--src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java6
62 files changed, 2064 insertions, 318 deletions
diff --git a/src/main/java/org/gnunet/consensus/ConcludeCallback.java b/src/main/java/org/gnunet/consensus/ConcludeCallback.java
index 7660c49..ebef5d2 100644
--- a/src/main/java/org/gnunet/consensus/ConcludeCallback.java
+++ b/src/main/java/org/gnunet/consensus/ConcludeCallback.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3public interface ConcludeCallback { 23public interface ConcludeCallback {
diff --git a/src/main/java/org/gnunet/consensus/ConcludeDoneMessage.java b/src/main/java/org/gnunet/consensus/ConcludeDoneMessage.java
index 51757aa..bf63ed7 100644
--- a/src/main/java/org/gnunet/consensus/ConcludeDoneMessage.java
+++ b/src/main/java/org/gnunet/consensus/ConcludeDoneMessage.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3 23
diff --git a/src/main/java/org/gnunet/consensus/ConcludeMessage.java b/src/main/java/org/gnunet/consensus/ConcludeMessage.java
index 7b43928..a588c5e 100644
--- a/src/main/java/org/gnunet/consensus/ConcludeMessage.java
+++ b/src/main/java/org/gnunet/consensus/ConcludeMessage.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3import org.gnunet.construct.FillWith; 23import org.gnunet.construct.FillWith;
diff --git a/src/main/java/org/gnunet/consensus/Consensus.java b/src/main/java/org/gnunet/consensus/Consensus.java
index 322599c..4049c47 100644
--- a/src/main/java/org/gnunet/consensus/Consensus.java
+++ b/src/main/java/org/gnunet/consensus/Consensus.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3import org.gnunet.mq.Envelope; 23import org.gnunet.mq.Envelope;
diff --git a/src/main/java/org/gnunet/consensus/ConsensusElement.java b/src/main/java/org/gnunet/consensus/ConsensusElement.java
index 846e72a..bc8942e 100644
--- a/src/main/java/org/gnunet/consensus/ConsensusElement.java
+++ b/src/main/java/org/gnunet/consensus/ConsensusElement.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3 23
diff --git a/src/main/java/org/gnunet/consensus/InsertDoneCallback.java b/src/main/java/org/gnunet/consensus/InsertDoneCallback.java
index f0e86ca..2d0df61 100644
--- a/src/main/java/org/gnunet/consensus/InsertDoneCallback.java
+++ b/src/main/java/org/gnunet/consensus/InsertDoneCallback.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3public interface InsertDoneCallback { 23public interface InsertDoneCallback {
diff --git a/src/main/java/org/gnunet/consensus/InsertElementMessage.java b/src/main/java/org/gnunet/consensus/InsertElementMessage.java
index fd0ff67..a080ce6 100644
--- a/src/main/java/org/gnunet/consensus/InsertElementMessage.java
+++ b/src/main/java/org/gnunet/consensus/InsertElementMessage.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3import org.gnunet.construct.FillWith; 23import org.gnunet.construct.FillWith;
diff --git a/src/main/java/org/gnunet/consensus/NewElementCallback.java b/src/main/java/org/gnunet/consensus/NewElementCallback.java
index 4b07a71..3edde36 100644
--- a/src/main/java/org/gnunet/consensus/NewElementCallback.java
+++ b/src/main/java/org/gnunet/consensus/NewElementCallback.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3public interface NewElementCallback { 23public interface NewElementCallback {
diff --git a/src/main/java/org/gnunet/consensus/NewElementMessage.java b/src/main/java/org/gnunet/consensus/NewElementMessage.java
index deb3634..817e510 100644
--- a/src/main/java/org/gnunet/consensus/NewElementMessage.java
+++ b/src/main/java/org/gnunet/consensus/NewElementMessage.java
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.consensus; 21package org.gnunet.consensus;
2 22
3import org.gnunet.construct.*; 23import org.gnunet.construct.*;
diff --git a/src/main/java/org/gnunet/mesh/Mesh.java b/src/main/java/org/gnunet/mesh/Mesh.java
index b66cc6f..f97a117 100644
--- a/src/main/java/org/gnunet/mesh/Mesh.java
+++ b/src/main/java/org/gnunet/mesh/Mesh.java
@@ -111,16 +111,17 @@ public class Mesh {
111 public class Tunnel<T> extends MessageQueue { 111 public class Tunnel<T> extends MessageQueue {
112 private T context; 112 private T context;
113 private final int opt; 113 private final int opt;
114 public final PeerIdentity peer; 114 final PeerIdentity peer;
115 public final int port; 115 final int port;
116 protected long tunnelId; 116 protected long tunnelId;
117 private boolean receive_done_expected = false; 117 private boolean receiveDoneExpected = false;
118 int ack_count = 0; 118 int ackCount = 0;
119 boolean destroyedByService;
119 120
120 /** 121 /**
121 * Canceler for the currently submitted envelope. 122 * Canceler for the currently submitted envelope.
122 */ 123 */
123 public Cancelable envelopeCanceler; 124 private Cancelable envelopeCanceler;
124 125
125 /** 126 /**
126 * Create a new tunnel (we're initiator and will be allowed to add/remove peers 127 * Create a new tunnel (we're initiator and will be allowed to add/remove peers
@@ -175,26 +176,28 @@ public class Mesh {
175 } 176 }
176 177
177 public void receiveDone() { 178 public void receiveDone() {
178 if (!receive_done_expected) 179 if (!receiveDoneExpected)
179 throw new AssertionError("unexpected call to receiveDone"); 180 throw new AssertionError("unexpected call to receiveDone");
180 LocalAckMessage am = new LocalAckMessage(); 181 LocalAckMessage am = new LocalAckMessage();
181 am.tid = tunnelId; 182 am.tid = tunnelId;
182 client.send(am); 183 client.send(am);
183 receive_done_expected = false; 184 receiveDoneExpected = false;
184 } 185 }
185 186
186 public void destroy() { 187 public void destroy() {
187 TunnelDestroyMessage m = new TunnelDestroyMessage(); 188 if (!destroyedByService) {
188 m.tunnel_id = tunnelId; 189 TunnelDestroyMessage m = new TunnelDestroyMessage();
189 m.reserved = new byte[32]; 190 m.tunnel_id = tunnelId;
190 client.send(m); 191 m.reserved = new byte[32];
191 tunnelMap.remove(m.tunnel_id); 192 client.send(m);
193 }
194 tunnelMap.remove(tunnelId);
192 } 195 }
193 196
194 @Override 197 @Override
195 protected void submit(Envelope ev) { 198 protected void submit(Envelope ev) {
196 logger.debug("submitting data message on tunnel {}", tunnelId); 199 logger.debug("submitting data message on tunnel {}", tunnelId);
197 if (ack_count <= 0) 200 if (ackCount <= 0)
198 throw new AssertionError(); 201 throw new AssertionError();
199 DataMessage m = new DataMessage(); 202 DataMessage m = new DataMessage();
200 m.payload = Construct.toBinary(GnunetMessage.fromBody(ev.message)); 203 m.payload = Construct.toBinary(GnunetMessage.fromBody(ev.message));
@@ -208,7 +211,7 @@ public class Mesh {
208 }); 211 });
209 client.send(mesh_ev); 212 client.send(mesh_ev);
210 envelopeCanceler = mesh_ev; 213 envelopeCanceler = mesh_ev;
211 ack_count -= 1; 214 ackCount -= 1;
212 } 215 }
213 216
214 @Override 217 @Override
@@ -227,10 +230,10 @@ public class Mesh {
227 context = newContext; 230 context = newContext;
228 } 231 }
229 232
230 public void handleAck() { 233 void handleAck() {
231 ack_count++; 234 ackCount++;
232 logger.debug("got ack for tunnel id " + tunnelId); 235 logger.debug("got ack for tunnel id " + tunnelId);
233 if (ack_count == 1) { 236 if (ackCount == 1) {
234 reportReadyForSubmit(); 237 reportReadyForSubmit();
235 } 238 }
236 } 239 }
@@ -250,10 +253,12 @@ public class Mesh {
250 Tunnel t = tunnelMap.get(m.tid); 253 Tunnel t = tunnelMap.get(m.tid);
251 if (t != null) 254 if (t != null)
252 { 255 {
253 if (t.receive_done_expected) 256 if (t.receiveDoneExpected)
254 logger.warn("got unexpected message from service"); 257 logger.warn("got unexpected message from service");
255 t.receive_done_expected = true; 258 t.receiveDoneExpected = true;
259 messageReceiver.setSender(t);
256 messageReceiver.visitAppropriate(Construct.parseAs(m.payload, GnunetMessage.class).body); 260 messageReceiver.visitAppropriate(Construct.parseAs(m.payload, GnunetMessage.class).body);
261 messageReceiver.setSender(null);
257 } 262 }
258 } 263 }
259 264
@@ -269,17 +274,21 @@ public class Mesh {
269 274
270 public void visit(TunnelDestroyMessage m) { 275 public void visit(TunnelDestroyMessage m) {
271 Tunnel t = tunnelMap.get(m.tunnel_id); 276 Tunnel t = tunnelMap.get(m.tunnel_id);
272 if (t == null) { 277 if (null == t) {
273 logger.warn("server got confused with tunnel IDs on destroy, ignoring message"); 278 logger.warn("server got confused with tunnel IDs on destroy, ignoring message");
274 return; 279 return;
275 } 280 }
281 t.destroyedByService = true;
276 t.destroy(); 282 t.destroy();
277 tunnelEndHandler.onTunnelEnd(t); 283 if (null != tunnelEndHandler) {
284 tunnelEndHandler.onTunnelEnd(t);
285 }
278 } 286 }
279 287
280 @Override 288 @Override
281 public void handleError() { 289 public void handleError() {
282 if (tunnelEndHandler != null) { 290 logger.warn("lost connection to mesh service, reconnecting");
291 if (null != tunnelEndHandler) {
283 for (Tunnel t : tunnelMap.values()) { 292 for (Tunnel t : tunnelMap.values()) {
284 tunnelEndHandler.onTunnelEnd(t); 293 tunnelEndHandler.onTunnelEnd(t);
285 } 294 }
@@ -293,13 +302,15 @@ public class Mesh {
293 } 302 }
294 303
295 /** 304 /**
296 * Connect to the mesh service. 305 * Connect to the mesh service, listening to the given ports.
297 * 306 *
298 * @param cfg configuration to use 307 * @param cfg configuration to use
299 * @param inboundTunnelHandler function called when an *inbound* tunnel is created 308 * @param inboundTunnelHandler function called when an *inbound* tunnel is created
300 * @param tunnelEndHandler function called when an *inbound* tunnel is destroyed by the 309 * @param tunnelEndHandler function called when an *inbound* tunnel is destroyed by the
301 * remote peer, it is *not* called if Tunnel.destroy 310 * remote peer, it is *not* called if Tunnel.destroy
302 * is called on the tunnel 311 * is called on the tunnel
312 * @param messageReceiver runabout for messages we are interested in
313 * @param ports ports to listen on
303 */ 314 */
304 public Mesh(Configuration cfg, InboundTunnelHandler inboundTunnelHandler, 315 public Mesh(Configuration cfg, InboundTunnelHandler inboundTunnelHandler,
305 TunnelEndHandler tunnelEndHandler, MeshRunabout messageReceiver, int... ports) { 316 TunnelEndHandler tunnelEndHandler, MeshRunabout messageReceiver, int... ports) {
@@ -317,6 +328,18 @@ public class Mesh {
317 client.send(ccm); 328 client.send(ccm);
318 } 329 }
319 330
331 /**
332 * Connect to the mesh service.
333 *
334 * @param cfg configuration to use
335 * @param tunnelEndHandler function called when an *inbound* tunnel is destroyed by the
336 * remote peer, it is *not* called if Tunnel.destroy
337 * is called on the tunnel
338 */
339 public Mesh(Configuration cfg, TunnelEndHandler tunnelEndHandler, MeshRunabout messageReceiver) {
340 this(cfg, null, tunnelEndHandler, messageReceiver);
341 }
342
320 public <T> Tunnel<T> createTunnel(PeerIdentity peer, int port, boolean nobuffer, boolean reliable, T initialContext) { 343 public <T> Tunnel<T> createTunnel(PeerIdentity peer, int port, boolean nobuffer, boolean reliable, T initialContext) {
321 return new Tunnel<T>(peer, port, nobuffer, reliable, initialContext); 344 return new Tunnel<T>(peer, port, nobuffer, reliable, initialContext);
322 } 345 }
diff --git a/src/main/java/org/gnunet/mesh/MeshRunabout.java b/src/main/java/org/gnunet/mesh/MeshRunabout.java
index ea4248c..bd7819e 100644
--- a/src/main/java/org/gnunet/mesh/MeshRunabout.java
+++ b/src/main/java/org/gnunet/mesh/MeshRunabout.java
@@ -9,11 +9,11 @@ import org.grothoff.Runabout;
9 * @author Florian Dold 9 * @author Florian Dold
10 */ 10 */
11public class MeshRunabout extends Runabout { 11public class MeshRunabout extends Runabout {
12 private PeerIdentity sender; 12 private Mesh.Tunnel sender;
13 /* package private */ void setSender(PeerIdentity sender) { 13 /* package private */ void setSender(Mesh.Tunnel sender) {
14 this.sender = sender; 14 this.sender = sender;
15 } 15 }
16 public PeerIdentity getSender() { 16 public Mesh.Tunnel getSender() {
17 return sender; 17 return sender;
18 } 18 }
19} 19}
diff --git a/src/main/java/org/gnunet/mesh/TunnelEndHandler.java b/src/main/java/org/gnunet/mesh/TunnelEndHandler.java
index e56fdd4..2a492ce 100644
--- a/src/main/java/org/gnunet/mesh/TunnelEndHandler.java
+++ b/src/main/java/org/gnunet/mesh/TunnelEndHandler.java
@@ -6,5 +6,12 @@ package org.gnunet.mesh;
6 * @author Florian Dold 6 * @author Florian Dold
7 */ 7 */
8public interface TunnelEndHandler { 8public interface TunnelEndHandler {
9 /**
10 * Called once a tunnel has been destroyed.
11 * The given tunnel can not be used anymore, and is only provided
12 * to identify the tunnel that has been destroyed.
13 *
14 * @param tunnel tunnel that has been destroyed
15 */
9 void onTunnelEnd(Mesh.Tunnel tunnel); 16 void onTunnelEnd(Mesh.Tunnel tunnel);
10} 17}
diff --git a/src/main/java/org/gnunet/requests/MatchingRequestContainer.java b/src/main/java/org/gnunet/requests/MatchingRequestContainer.java
index 656d162..a11807f 100644
--- a/src/main/java/org/gnunet/requests/MatchingRequestContainer.java
+++ b/src/main/java/org/gnunet/requests/MatchingRequestContainer.java
@@ -7,6 +7,9 @@ import org.gnunet.util.Cancelable;
7import java.util.Map; 7import java.util.Map;
8 8
9 9
10/**
11 * Container for requests that are responded to with a matching request identification
12 */
10public class MatchingRequestContainer<K, T extends RequestContainer.Request> extends RequestContainer { 13public class MatchingRequestContainer<K, T extends RequestContainer.Request> extends RequestContainer {
11 private Map<K,T> requests = Maps.newHashMap(); 14 private Map<K,T> requests = Maps.newHashMap();
12 private final MessageQueue mq; 15 private final MessageQueue mq;
@@ -48,4 +51,15 @@ public class MatchingRequestContainer<K, T extends RequestContainer.Request> ext
48 public T getRequest(K key) { 51 public T getRequest(K key) {
49 return requests.get(key); 52 return requests.get(key);
50 } 53 }
54
55 /**
56 * Retrieve the request matching the given key, and remove it.
57 * Return null if there is no matching request.
58 *
59 * @param key key to look for
60 * @return request, or null
61 */
62 public T pollRequest(K key) {
63 return requests.remove(key);
64 }
51} 65}
diff --git a/src/main/java/org/gnunet/testbed/CompressedConfig.java b/src/main/java/org/gnunet/testbed/CompressedConfig.java
index 24fdc0f..85c2510 100644
--- a/src/main/java/org/gnunet/testbed/CompressedConfig.java
+++ b/src/main/java/org/gnunet/testbed/CompressedConfig.java
@@ -1,3 +1,22 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009,2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
1package org.gnunet.testbed; 20package org.gnunet.testbed;
2 21
3import com.google.common.base.Charsets; 22import com.google.common.base.Charsets;
diff --git a/src/main/java/org/gnunet/testbed/Controller.java b/src/main/java/org/gnunet/testbed/Controller.java
index 059245e..3a4c540 100644
--- a/src/main/java/org/gnunet/testbed/Controller.java
+++ b/src/main/java/org/gnunet/testbed/Controller.java
@@ -1,13 +1,29 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009,2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
1package org.gnunet.testbed; 20package org.gnunet.testbed;
2 21
3import org.gnunet.mq.Envelope; 22import org.gnunet.mq.Envelope;
4import org.gnunet.requests.MatchingRequestContainer; 23import org.gnunet.requests.MatchingRequestContainer;
5import org.gnunet.requests.RequestContainer; 24import org.gnunet.requests.RequestContainer;
6import org.gnunet.requests.SequentialRequestContainer;
7import org.gnunet.testbed.callbacks.*; 25import org.gnunet.testbed.callbacks.*;
8import org.gnunet.testbed.messages.ControllerInitMessage; 26import org.gnunet.testbed.messages.*;
9import org.gnunet.testbed.messages.PeerCreateMessage;
10import org.gnunet.testbed.messages.PeerCreateSuccessMessage;
11import org.gnunet.util.Cancelable; 27import org.gnunet.util.Cancelable;
12import org.gnunet.util.Client; 28import org.gnunet.util.Client;
13import org.gnunet.util.Configuration; 29import org.gnunet.util.Configuration;
@@ -25,15 +41,31 @@ import org.slf4j.LoggerFactory;
25 * links are established via TCP/IP on the controller's service port. 41 * links are established via TCP/IP on the controller's service port.
26 */ 42 */
27public class Controller { 43public class Controller {
28private static final Logger logger = LoggerFactory 44 private static final Logger logger = LoggerFactory
29 .getLogger(Controller.class); 45 .getLogger(Controller.class);
30 46
31 public static int ET_PEER_START = 0; 47 public static class EventTypes {
32 public static int ET_PEER_STOP = 1; 48 /**
33 public static int ET_CONNECT = 2; 49 * A peer has been started.
34 public static int ET_DISCONNECT = 3; 50 */
35 public static int ET_OPERATION_FINISHED = 4; 51 public static final int PEER_START = 0;
36 52 /**
53 * A peer has been stopped.
54 */
55 public static final int PEER_STOP = 1;
56 /**
57 * A connection between two peers has been established.
58 */
59 public static final int PEERS_CONNECT = 2;
60 /**
61 * A connection between two peers has been torn down.
62 */
63 public static final int PEERS_DISCONNECT = 3;
64 /**
65 * An operation has finished.
66 */
67 public static final int OPERATION_FINISHED = 4;
68 }
37 69
38 /** 70 /**
39 * Client connecting to the testbed service. 71 * Client connecting to the testbed service.
@@ -45,26 +77,42 @@ private static final Logger logger = LoggerFactory
45 */ 77 */
46 private Host host; 78 private Host host;
47 79
48 private int operationCounter; 80 private int operationCounter = 1;
49 private int peerCounter; 81 private int peerCounter;
50 82
51 /** 83 /**
52 * Request queue (called operation queue in the GNUnet C implementation) 84 * Request queue (akin to operation queue(s) in the GNUnet C implementation).
53 */ 85 */
54 private MatchingRequestContainer<Long,RequestContainer.Request> requests; 86 private MatchingRequestContainer<Long,OperationRequest> requests;
87
88 abstract class OperationRequest extends RequestContainer.Request {
89 protected final long operationId;
90 public OperationRequest() {
91 operationId = (((long) host.id) << 32) | (long) operationCounter++;
92 }
93 }
55 94
95 abstract class GenericOperationRequest extends OperationRequest {
96 final protected OperationCompletionCallback cb;
97 public GenericOperationRequest(OperationCompletionCallback cb) {
98 this.cb = cb;
99 }
100 void onSuccess() {
101 cb.onCompletion();
102 }
103 }
56 104
57 class PeerCreateRequest extends RequestContainer.Request { 105 class PeerCreateRequest extends OperationRequest {
58 private final Host host; 106 final Host host;
59 private final Configuration cfg; 107 final Configuration cfg;
60 private final PeerCreateCallback cb; 108 final PeerCreateCallback cb;
61 public long op_id; 109 final int peer_id;
62 110
63 public PeerCreateRequest(Host host, Configuration cfg, PeerCreateCallback cb) { 111 public PeerCreateRequest(Host host, Configuration cfg, PeerCreateCallback cb) {
64 this.host = host; 112 this.host = host;
65 this.cfg = cfg; 113 this.cfg = cfg;
66 this.cb = cb; 114 this.cb = cb;
67 this.op_id = getNextOpId(); 115 this.peer_id = peerCounter++;
68 } 116 }
69 117
70 @Override 118 @Override
@@ -72,48 +120,223 @@ private static final Logger logger = LoggerFactory
72 CompressedConfig ccfg = new CompressedConfig(cfg); 120 CompressedConfig ccfg = new CompressedConfig(cfg);
73 PeerCreateMessage m = new PeerCreateMessage(); 121 PeerCreateMessage m = new PeerCreateMessage();
74 m.host_id = host.id; 122 m.host_id = host.id;
75 m.operation_id = op_id; 123 m.operation_id = operationId;
76 m.peer_id = peerCounter++; 124 m.peer_id = peer_id;
77 m.compressed_config = ccfg.compressed_data; 125 m.compressed_config = ccfg.compressed_data;
78 m.config_size = ccfg.getUncompressedSize(); 126 m.config_size = ccfg.getUncompressedSize();
127 System.out.println("create request with opid " + m.operation_id);
128 return new Envelope(m);
129 }
130 }
131
132 class PeerDestroyRequest extends GenericOperationRequest {
133 final int peerId;
134 public PeerDestroyRequest(Peer p, OperationCompletionCallback cb) {
135 super(cb);
136 peerId = p.peerId;
137 }
138
139 @Override
140 public Envelope assembleRequest() {
141 PeerDestroyMessage m = new PeerDestroyMessage();
142 m.operation_id = operationId;
143 m.peer_id = peerId;
144
145 System.out.println("destroy request with opid " + m.operation_id);
79 return new Envelope(m); 146 return new Envelope(m);
80 } 147 }
81 } 148 }
82 149
83 class PeerStartRequest extends RequestContainer.Request { 150 class PeerInformationRequest extends OperationRequest {
151 final int peerId;
152 final PeerInformationCallback cb;
153 public PeerInformationRequest(Peer peer, PeerInformationCallback cb) {
154 peerId = peer.peerId;
155 this.cb = cb;
156 }
84 157
85 @Override 158 @Override
86 public Envelope assembleRequest() { 159 public Envelope assembleRequest() {
87 return null; //To change body of implemented methods use File | Settings | File Templates. 160 PeerGetInformationMessage m = new PeerGetInformationMessage();
161 m.operationId = operationId;
162 m.peerId = peerId;
163 return new Envelope(m);
88 } 164 }
89 } 165 }
90 166
91 class PeerStopRequest extends RequestContainer.Request { 167 class PeerUpdateConfigurationRequest extends GenericOperationRequest {
168 final int peerId;
169 final Configuration cfg;
170 public PeerUpdateConfigurationRequest(Peer peer, OperationCompletionCallback cb, Configuration cfg) {
171 super(cb);
172 peerId = peer.peerId;
173 this.cfg = cfg;
174 }
175
176 @Override
177 public Envelope assembleRequest() {
178 PeerReconfigureMessage m = new PeerReconfigureMessage();
179 m.operationId = operationId;
180 m.peerId = peerId;
181 CompressedConfig ccfg = new CompressedConfig(cfg);
182 m.uncompressedConfigSize = ccfg.getUncompressedSize();
183 m.compressedConfig = ccfg.compressed_data;
184
185 System.out.println("compressed config size " +m.compressedConfig.length);
186 return new Envelope(m);
187 }
188 }
92 189
190 class PeerManageServiceRequest extends OperationRequest {
191 final Peer peer;
192 final boolean start;
193 final String serviceName;
194 public PeerManageServiceRequest(Peer peer, String serviceName, boolean start) {
195 this.peer = peer;
196 this.start = start;
197 this.serviceName = serviceName;
198 }
93 @Override 199 @Override
94 public Envelope assembleRequest() { 200 public Envelope assembleRequest() {
95 return null; //To change body of implemented methods use File | Settings | File Templates. 201 ManagePeerServiceMessage m = new ManagePeerServiceMessage();
202 m.operationId = operationId;
203 m.peerId = peer.peerId;
204 m.serviceName = serviceName;
205 m.start = start;
206 return new Envelope(m);
96 } 207 }
97 } 208 }
98 209
99 class ConnectOverlayRequest extends RequestContainer.Request { 210 class PeerStartRequest extends OperationRequest {
211 final Peer peer;
212 final PeerChurnCallback peerChurnCallback;
213
214 public PeerStartRequest(Peer peer, PeerChurnCallback peerChurnCallback) {
215 this.peer = peer;
216 this.peerChurnCallback = peerChurnCallback;
217 }
218
100 @Override 219 @Override
101 public Envelope assembleRequest() { 220 public Envelope assembleRequest() {
102 return null; //To change body of implemented methods use File | Settings | File Templates. 221 PeerStartMessage m = new PeerStartMessage();
222 m.operation_id = operationId;
223 m.peer_id = peer.peerId;
224 return new Envelope(m);
225 }
226 }
227
228 class PeerStopRequest extends OperationRequest {
229 final Peer peer;
230 final PeerChurnCallback peerChurnCallback;
231
232 public PeerStopRequest(Peer peer, PeerChurnCallback peerChurnCallback) {
233 this.peer = peer;
234 this.peerChurnCallback = peerChurnCallback;
235 }
236
237 @Override
238 public Envelope assembleRequest() {
239 PeerStopMessage m = new PeerStopMessage();
240 m.operation_id = operationId;
241 m.peer_id = peer.peerId;
242 return new Envelope(m);
243 }
244 }
245
246 class PeerConnectOverlayRequest extends OperationRequest {
247 final Peer peer1;
248 final Peer peer2;
249 final OperationCompletionCallback cb;
250 public PeerConnectOverlayRequest(Peer peer1, Peer peer2, OperationCompletionCallback cb) {
251 this.peer1 = peer1;
252 this.peer2 = peer2;
253 this.cb = cb;
254 }
255 @Override
256 public Envelope assembleRequest() {
257 OverlayConnectMessage m = new OverlayConnectMessage();
258 m.operationId = operationId;
259 m.peer1 = peer1.peerId;
260 m.peer2 = peer2.peerId;
261 m.hostOfPeer2 = peer2.getHost().id;
262 return new Envelope(m);
103 } 263 }
104 } 264 }
105 265
106 266
107 public class ControllerMessageReceiver extends RunaboutMessageReceiver { 267 public class ControllerMessageReceiver extends RunaboutMessageReceiver {
268 public void visit(PeerEventMessage m) {
269 RequestContainer.Request r = requests.getRequest(m.operationId);
270 if (null == r) {
271 logger.error("no matching peer event request for op id %s", m.operationId);
272 return;
273 }
274 if (r instanceof PeerStartRequest && m.eventType == EventTypes.PEER_START) {
275 PeerStartRequest psr = (PeerStartRequest) r;
276 psr.peerChurnCallback.onChurnSuccess();
277 } else if (r instanceof PeerStopRequest && m.eventType == EventTypes.PEER_STOP) {
278 PeerStopRequest psr = (PeerStopRequest) r;
279 psr.peerChurnCallback.onChurnSuccess();
280 } else {
281 logger.error("unexpected peer event message, event type %s and request %s",
282 m.eventType, r);
283 }
284 }
108 public void visit(PeerCreateSuccessMessage m) { 285 public void visit(PeerCreateSuccessMessage m) {
109 RequestContainer.Request r = requests.getRequest(m.operation_id); 286 RequestContainer.Request r = requests.getRequest(m.operationId);
110 if (!(r instanceof PeerCreateRequest)) { 287 if (!(r instanceof PeerCreateRequest)) {
111 logger.warn("response to peer create request does not match"); 288 logger.warn("response to peer create request does not match");
112 return; 289 return;
113 } 290 }
114 PeerCreateRequest pcr = (PeerCreateRequest) r; 291 PeerCreateRequest pcr = (PeerCreateRequest) r;
115 // FIXME: create peer 292 Peer p = new Peer(pcr.peer_id);
116 pcr.cb.onPeerCreated(null); 293 pcr.cb.onPeerCreated(p);
294 }
295 public void visit(PeerInformationMessage m) {
296 RequestContainer.Request r = requests.getRequest(m.operationId);
297 if (null == r) {
298 logger.error("unexpected peer information message (opid={})", m.operationId);
299 return;
300 }
301 if (!(r instanceof PeerInformationRequest)) {
302 logger.warn("response to peer create request does not match");
303 return;
304 }
305 PeerInformationRequest pir = (PeerInformationRequest) r;
306 CompressedConfig ccfg = new CompressedConfig(m.compressedConfig);
307 pir.cb.onSuccess(m.peerIdentity, ccfg.decompress());
308 }
309 public void visit(GenericOperationSuccessMessage m) {
310 OperationRequest r = requests.getRequest(m.operationId);
311 if (null == r) {
312 logger.error("unexpected generic success message (opid={})", m.operationId);
313 return;
314 }
315 if (!(r instanceof GenericOperationRequest)) {
316 logger.error(String.format(
317 "got GenericOperationSuccessMessage as response to request '%s', opid %s; event type %s",
318 r.getClass(), m.operationId, m.eventType));
319 return;
320 }
321 GenericOperationRequest gr = (GenericOperationRequest) r;
322 gr.onSuccess();
323 }
324 public void visit(ConnectionEventMessage m) {
325 OperationRequest r = requests.getRequest(m.operationId);
326 if (null == r) {
327 logger.error("unexpected connection event message (opid={})", m.operationId);
328 return;
329 }
330 if (!(r instanceof PeerConnectOverlayRequest)) {
331 logger.error("unexpected connection event message for operation {}", r.getClass());
332 return;
333 }
334 PeerConnectOverlayRequest cr = (PeerConnectOverlayRequest) r;
335 cr.cb.onCompletion();
336
337 }
338 public void visit(OperationFailEventMessage m) {
339 logger.error("operation failed: " + m.errorMessage);
117 } 340 }
118 @Override 341 @Override
119 public void handleError() { 342 public void handleError() {
@@ -121,11 +344,6 @@ private static final Logger logger = LoggerFactory
121 } 344 }
122 } 345 }
123 346
124 private long getNextOpId() {
125 return (((long) host.id) << 32) | (long) operationCounter++;
126 }
127
128
129 /** 347 /**
130 * Connect to a controller process. The configuration to use for the connection 348 * Connect to a controller process. The configuration to use for the connection
131 * is retreived from the given host where a controller is started using 349 * is retreived from the given host where a controller is started using
@@ -144,7 +362,7 @@ private static final Logger logger = LoggerFactory
144 this.host = host; 362 this.host = host;
145 client = new Client("testbed", host.cfg); 363 client = new Client("testbed", host.cfg);
146 client.installReceiver(new ControllerMessageReceiver()); 364 client.installReceiver(new ControllerMessageReceiver());
147 requests = new MatchingRequestContainer<Long, RequestContainer.Request>(client); 365 requests = new MatchingRequestContainer<Long, OperationRequest>(client);
148 366
149 ControllerInitMessage m = new ControllerInitMessage(); 367 ControllerInitMessage m = new ControllerInitMessage();
150 m.event_mask = event_mask; 368 m.event_mask = event_mask;
@@ -175,14 +393,13 @@ private static final Logger logger = LoggerFactory
175 * 'Peer.getInformation'. 393 * 'Peer.getInformation'.
176 * 394 *
177 * @param host host to run the peer on; cannot be NULL 395 * @param host host to run the peer on; cannot be NULL
178 * @param cfg Template configuration to use for the peer. Should exist until 396 * @param cfg Template configuration to use for the peer.
179 * operation is cancelled or GNUNET_TESTBED_operation_done() is called
180 * @param cb the callback to call when the peer has been created 397 * @param cb the callback to call when the peer has been created
181 * @return the operation handle 398 * @return the operation handle
182 */ 399 */
183 public Cancelable createPeer(Host host, Configuration cfg, PeerCreateCallback cb) { 400 public Cancelable createPeer(Host host, Configuration cfg, PeerCreateCallback cb) {
184 PeerCreateRequest r = new PeerCreateRequest(host, cfg, cb); 401 PeerCreateRequest r = new PeerCreateRequest(host, cfg, cb);
185 return requests.addRequest(r.op_id, r); 402 return requests.addRequest(r.operationId, r);
186 } 403 }
187 404
188 /** 405 /**
@@ -220,7 +437,7 @@ private static final Logger logger = LoggerFactory
220 * controller via TCP/IP 437 * controller via TCP/IP
221 * @return the operation handle 438 * @return the operation handle
222 */ 439 */
223 public Operation link(Host delegated_host, Host slave_host, boolean is_subordinate) { 440 public Cancelable link(Host delegated_host, Host slave_host, boolean is_subordinate) {
224 // low priority 441 // low priority
225 throw new UnsupportedOperationException("not yet implemented"); 442 throw new UnsupportedOperationException("not yet implemented");
226 } 443 }
@@ -249,16 +466,44 @@ private static final Logger logger = LoggerFactory
249 * at a particular host. 466 * at a particular host.
250 */ 467 */
251 public class Peer { 468 public class Peer {
252 public Operation start(PeerChurnCallback peerChurnCallback) { 469 final private int peerId;
253 return null; 470
471 /**
472 * Private constructor for the peer, creates the peer with the given id,
473 * and, implicitly the containing controller.
474 *
475 * @param peerId id for the peer
476 */
477 private Peer(int peerId) {
478 this.peerId = peerId;
254 } 479 }
255 480
256 public Operation stop(PeerChurnCallback peerChurnCallback) { 481 /**
257 return null; 482 * Start this peer
483 *
484 * @param peerChurnCallback completion callback
485 * @return handle to cancel the operation
486 */
487 public Cancelable start(PeerChurnCallback peerChurnCallback) {
488 PeerStartRequest r = new PeerStartRequest(this, peerChurnCallback);
489 return requests.addRequest(r.operationId, r);
258 } 490 }
259 491
260 public Operation getInformation() { 492 /**
261 return null; 493 * Stop this peer
494 *
495 * @param peerChurnCallback completion callback
496 * @return handle to cancel the operation
497 */
498 public Cancelable stop(PeerChurnCallback peerChurnCallback) {
499 PeerStopRequest r = new PeerStopRequest(this, peerChurnCallback);
500 return requests.addRequest(r.operationId, r);
501 }
502
503
504 public Cancelable requestInformation(PeerInformationCallback cb) {
505 PeerInformationRequest r = new PeerInformationRequest(this, cb);
506 return requests.addRequest(r.operationId, r);
262 } 507 }
263 508
264 /* 509 /*
@@ -266,8 +511,9 @@ private static final Logger logger = LoggerFactory
266 * peer is stopped. Ports and paths cannot be changed this 511 * peer is stopped. Ports and paths cannot be changed this
267 * way. 512 * way.
268 */ 513 */
269 public Operation updateConfiguration(Configuration cfg) { 514 public Cancelable updateConfiguration(Configuration cfg, OperationCompletionCallback cb) {
270 return null; 515 PeerUpdateConfigurationRequest r = new PeerUpdateConfigurationRequest(this, cb, cfg);
516 return requests.addRequest(r.operationId, r);
271 } 517 }
272 518
273 /* 519 /*
@@ -275,26 +521,58 @@ private static final Logger logger = LoggerFactory
275 * peer is stopped. Ports and paths cannot be changed this 521 * peer is stopped. Ports and paths cannot be changed this
276 * way. 522 * way.
277 */ 523 */
278 public Operation destroy() { 524 public Cancelable destroy(OperationCompletionCallback cb) {
279 return null; 525 PeerDestroyRequest r = new PeerDestroyRequest(this, cb);
526 return requests.addRequest(r.operationId, r);
280 } 527 }
281 528
282 public Operation manageService(String serviceName, boolean start) { 529 public Cancelable manageService(String serviceName, boolean start, OperationCompletionCallback cb) {
283 return null; 530 PeerManageServiceRequest r = new PeerManageServiceRequest(this, serviceName, start);
531 return requests.addRequest(r.operationId, r);
284 } 532 }
285 533
286 /** 534 /**
287 * Both peers must have been started before calling this function. 535 * Both peers must have been started before calling this function.
288 * This function then obtains a HELLO from this peer, gives it to 'otherPeer' 536 * This function then obtains a HELLO from this peer, gives it to 'otherPeer'
289 * and asks 'otherPeer' to connect to this peer.. 537 * and asks 'otherPeer' to connect to this peer.
538 *
539 * @param otherPeer peer to connect this peer to
540 * @param cb callback object to signal completion or failure
541 * @return token to cancel the request
542 *
290 */ 543 */
291 public Operation connectOverlay(OperationCompletionCallback cb, Peer otherPeer) { 544 public Cancelable connectOverlay(Peer otherPeer, OperationCompletionCallback cb) {
292 return null; 545 PeerConnectOverlayRequest r = new PeerConnectOverlayRequest(this, otherPeer, cb);
546 return requests.addRequest(r.operationId, r);
293 } 547 }
294 548
295 public Operation getServiceConnection(String serviceName /*,... */) { 549
550 /**
551 * Connect to a service offered by the given peer. Will ensure that
552 * the request is queued to not overwhelm our ability to create and
553 * maintain connections with other systems. The actual service
554 * handle is then returned via the 'op_result' member in the event
555 * callback. The 'ca' callback is used to create the connection
556 * when the time is right; the 'da' callback will be used to
557 * destroy the connection (upon 'GNUNET_TESTBED_operation_done').
558 * 'GNUNET_TESTBED_operation_done' can be used to abort this
559 * operation until the event callback has been called.
560 *
561 * @param serviceName name of the service to connect to
562 * @param serviceAdapter callback object for connection establishment and tear-down.
563 * @return handle for the operation
564 */
565 public Cancelable getServiceConnection(String serviceName, ServiceAdapter serviceAdapter) {
296 return null; 566 return null;
297 } 567 }
298 568
569 /**
570 * Get the host this peer is running on.
571 *
572 * @return the host this peer is running on
573 */
574 public Host getHost() {
575 return Controller.this.host;
576 }
299 } 577 }
300} 578}
diff --git a/src/main/java/org/gnunet/testbed/Operation.java b/src/main/java/org/gnunet/testbed/Operation.java
deleted file mode 100644
index 4403540..0000000
--- a/src/main/java/org/gnunet/testbed/Operation.java
+++ /dev/null
@@ -1,11 +0,0 @@
1package org.gnunet.testbed;
2
3/**
4 * Created with IntelliJ IDEA.
5 * User: dold
6 * Date: 8/25/13
7 * Time: 1:26 PM
8 * To change this template use File | Settings | File Templates.
9 */
10public interface Operation {
11}
diff --git a/src/main/java/org/gnunet/testbed/callbacks/OperationCompletionCallback.java b/src/main/java/org/gnunet/testbed/callbacks/OperationCompletionCallback.java
index e33364b..c2f4f4e 100644
--- a/src/main/java/org/gnunet/testbed/callbacks/OperationCompletionCallback.java
+++ b/src/main/java/org/gnunet/testbed/callbacks/OperationCompletionCallback.java
@@ -1,11 +1,7 @@
1package org.gnunet.testbed.callbacks; 1package org.gnunet.testbed.callbacks;
2 2
3/** 3
4 * Created with IntelliJ IDEA.
5 * User: dold
6 * Date: 8/25/13
7 * Time: 1:35 PM
8 * To change this template use File | Settings | File Templates.
9 */
10public interface OperationCompletionCallback { 4public interface OperationCompletionCallback {
5 void onCompletion();
6 void onError(String emsg);
11} 7}
diff --git a/src/main/java/org/gnunet/testbed/callbacks/PeerInformationCallback.java b/src/main/java/org/gnunet/testbed/callbacks/PeerInformationCallback.java
new file mode 100644
index 0000000..3c9064d
--- /dev/null
+++ b/src/main/java/org/gnunet/testbed/callbacks/PeerInformationCallback.java
@@ -0,0 +1,29 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.testbed.callbacks;
22
23
24import org.gnunet.util.Configuration;
25import org.gnunet.util.PeerIdentity;
26
27public interface PeerInformationCallback {
28 void onSuccess(PeerIdentity peerIdentity, Configuration configuration);
29}
diff --git a/src/main/java/org/gnunet/testbed/callbacks/ServiceAdapter.java b/src/main/java/org/gnunet/testbed/callbacks/ServiceAdapter.java
new file mode 100644
index 0000000..9b3fef7
--- /dev/null
+++ b/src/main/java/org/gnunet/testbed/callbacks/ServiceAdapter.java
@@ -0,0 +1,28 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.testbed.callbacks;
22
23import org.gnunet.util.Configuration;
24
25public interface ServiceAdapter {
26 void onConnect(Configuration cfg);
27 void onDisconnect();
28}
diff --git a/src/main/java/org/gnunet/testbed/messages/ConnectionEventMessage.java b/src/main/java/org/gnunet/testbed/messages/ConnectionEventMessage.java
index 094ee1b..a6e2370 100644
--- a/src/main/java/org/gnunet/testbed/messages/ConnectionEventMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/ConnectionEventMessage.java
@@ -1,11 +1,47 @@
1package org.gnunet.testbed.messages; 1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
2 14
3/** 15 You should have received a copy of the GNU General Public License
4 * Created with IntelliJ IDEA. 16 along with GNUnet; see the file COPYING. If not, write to the
5 * User: dold 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
6 * Date: 9/10/13 18 Boston, MA 02111-1307, USA.
7 * Time: 1:37 PM
8 * To change this template use File | Settings | File Templates.
9 */ 19 */
10public class ConnectionEventMessage { 20
21package org.gnunet.testbed.messages;
22
23
24import org.gnunet.construct.UInt32;
25import org.gnunet.construct.UInt64;
26import org.gnunet.construct.UnionCase;
27import org.gnunet.util.GnunetMessage;
28
29@UnionCase(472)
30public class ConnectionEventMessage implements GnunetMessage.Body {
31 /**
32 * 'enum GNUNET_TESTBED_EventType' (in NBO);
33 * either GNUNET_TESTBED_ET_CONNECT or GNUNET_TESTBED_ET_DISCONNECT.
34 */
35 @UInt32
36 public int eventType;
37
38 @UInt32
39 public int peer1;
40
41 @UInt32
42 public int peer2;
43
44 @UInt64
45 public long operationId;
46
11} 47}
diff --git a/src/main/java/org/gnunet/testbed/messages/ControllerInitMessage.java b/src/main/java/org/gnunet/testbed/messages/ControllerInitMessage.java
index 8255662..b60221c 100644
--- a/src/main/java/org/gnunet/testbed/messages/ControllerInitMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/ControllerInitMessage.java
@@ -1,3 +1,22 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
1package org.gnunet.testbed.messages; 20package org.gnunet.testbed.messages;
2 21
3 22
@@ -8,7 +27,7 @@ import org.gnunet.construct.ZeroTerminatedString;
8import org.gnunet.util.GnunetMessage; 27import org.gnunet.util.GnunetMessage;
9 28
10/** 29/**
11 * Initial message from a client to a testing control service. 30 * Initial message from a client to a testbed control service.
12 */ 31 */
13@UnionCase(460) 32@UnionCase(460)
14public class ControllerInitMessage implements GnunetMessage.Body { 33public class ControllerInitMessage implements GnunetMessage.Body {
diff --git a/src/main/java/org/gnunet/testbed/messages/CreatePeerSuccessMessage.java b/src/main/java/org/gnunet/testbed/messages/CreatePeerSuccessMessage.java
deleted file mode 100644
index 984e252..0000000
--- a/src/main/java/org/gnunet/testbed/messages/CreatePeerSuccessMessage.java
+++ /dev/null
@@ -1,5 +0,0 @@
1package org.gnunet.testbed.messages;
2
3
4public class CreatePeerSuccessMessage {
5}
diff --git a/src/main/java/org/gnunet/testbed/messages/GenericOperationSuccessMessage.java b/src/main/java/org/gnunet/testbed/messages/GenericOperationSuccessMessage.java
index 33c4a7a..c2388ba 100644
--- a/src/main/java/org/gnunet/testbed/messages/GenericOperationSuccessMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/GenericOperationSuccessMessage.java
@@ -1,11 +1,19 @@
1package org.gnunet.testbed.messages; 1package org.gnunet.testbed.messages;
2 2
3import org.gnunet.construct.UInt32;
4import org.gnunet.construct.UInt64;
5import org.gnunet.construct.UnionCase;
6import org.gnunet.util.GnunetMessage;
7
3/** 8/**
4 * Created with IntelliJ IDEA. 9 * Event notification from a controller to a client for
5 * User: dold 10 * a generic operational success where the operation does
6 * Date: 9/10/13 11 * not return any data.
7 * Time: 2:30 AM
8 * To change this template use File | Settings | File Templates.
9 */ 12 */
10public class GenericOperationSuccessMessage { 13@UnionCase(475)
14public class GenericOperationSuccessMessage implements GnunetMessage.Body {
15 @UInt32
16 public int eventType;
17 @UInt64
18 public long operationId;
11} 19}
diff --git a/src/main/java/org/gnunet/testbed/messages/ManagePeerServiceMessage.java b/src/main/java/org/gnunet/testbed/messages/ManagePeerServiceMessage.java
index deb40ad..c2f8996 100644
--- a/src/main/java/org/gnunet/testbed/messages/ManagePeerServiceMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/ManagePeerServiceMessage.java
@@ -1,5 +1,29 @@
1package org.gnunet.testbed.messages; 1package org.gnunet.testbed.messages;
2 2
3 3
4public class ManagePeerServiceMessage { 4import org.gnunet.construct.*;
5import org.gnunet.util.GnunetMessage;
6
7@UnionCase(483)
8public class ManagePeerServiceMessage implements GnunetMessage.Body {
9 /**
10 * Testbed-internal ID of the target peer.
11 */
12 @UInt32
13 public int peerId;
14
15 /**
16 * Operation ID.
17 */
18 @UInt64
19 public long operationId;
20
21 @UInt8
22 public boolean start;
23
24 /**
25 * Name of the service to start or stop.
26 */
27 @ZeroTerminatedString(optional = false)
28 public String serviceName;
5} 29}
diff --git a/src/main/java/org/gnunet/testbed/messages/OperationFailEventMessage.java b/src/main/java/org/gnunet/testbed/messages/OperationFailEventMessage.java
index b934e22..be306b7 100644
--- a/src/main/java/org/gnunet/testbed/messages/OperationFailEventMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/OperationFailEventMessage.java
@@ -1,11 +1,18 @@
1package org.gnunet.testbed.messages; 1package org.gnunet.testbed.messages;
2 2
3/** 3import org.gnunet.construct.UInt32;
4 * Created with IntelliJ IDEA. 4import org.gnunet.construct.UInt64;
5 * User: dold 5import org.gnunet.construct.UnionCase;
6 * Date: 9/10/13 6import org.gnunet.construct.ZeroTerminatedString;
7 * Time: 2:30 AM 7import org.gnunet.util.GnunetMessage;
8 * To change this template use File | Settings | File Templates. 8
9 */ 9
10public class OperationFailEventMessage { 10@UnionCase(473)
11public class OperationFailEventMessage implements GnunetMessage.Body {
12 @UInt32
13 public int eventType;
14 @UInt64
15 public long operationId;
16 @ZeroTerminatedString
17 public String errorMessage;
11} 18}
diff --git a/src/main/java/org/gnunet/testbed/messages/OverlayConnectMessage.java b/src/main/java/org/gnunet/testbed/messages/OverlayConnectMessage.java
index 8bfb07e..2447bf7 100644
--- a/src/main/java/org/gnunet/testbed/messages/OverlayConnectMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/OverlayConnectMessage.java
@@ -21,7 +21,7 @@ public class OverlayConnectMessage implements GnunetMessage.Body {
21 * Operation ID that is used to identify this operation. 21 * Operation ID that is used to identify this operation.
22 */ 22 */
23 @UInt64 23 @UInt64
24 public int operation_id; 24 public long operationId;
25 25
26 /** 26 /**
27 * Unique ID for the second peer. 27 * Unique ID for the second peer.
@@ -33,5 +33,5 @@ public class OverlayConnectMessage implements GnunetMessage.Body {
33 * The ID of the host which runs peer2 33 * The ID of the host which runs peer2
34 */ 34 */
35 @UInt32 35 @UInt32
36 public int peer2_host; 36 public int hostOfPeer2;
37} 37}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerConfigurationInformationMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerConfigurationInformationMessage.java
deleted file mode 100644
index 8c0ea97..0000000
--- a/src/main/java/org/gnunet/testbed/messages/PeerConfigurationInformationMessage.java
+++ /dev/null
@@ -1,8 +0,0 @@
1package org.gnunet.testbed.messages;
2
3/**
4 * Peer configuration and identity reply from controller to a client.
5 */
6public class PeerConfigurationInformationMessage {
7
8}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerCreateSuccessMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerCreateSuccessMessage.java
index 837f2d9..f302136 100644
--- a/src/main/java/org/gnunet/testbed/messages/PeerCreateSuccessMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/PeerCreateSuccessMessage.java
@@ -13,5 +13,5 @@ public class PeerCreateSuccessMessage implements GnunetMessage.Body {
13 @UInt32 13 @UInt32
14 public int peer_id; 14 public int peer_id;
15 @UInt64 15 @UInt64
16 public long operation_id; 16 public long operationId;
17} 17}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerDestroyMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerDestroyMessage.java
index 6b4f53c..eddccb7 100644
--- a/src/main/java/org/gnunet/testbed/messages/PeerDestroyMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/PeerDestroyMessage.java
@@ -11,5 +11,5 @@ public class PeerDestroyMessage implements GnunetMessage.Body {
11 @UInt32 11 @UInt32
12 public int peer_id; 12 public int peer_id;
13 @UInt64 13 @UInt64
14 public int operation_id; 14 public long operation_id;
15} 15}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerEventMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerEventMessage.java
index 3512d5d..44490cd 100644
--- a/src/main/java/org/gnunet/testbed/messages/PeerEventMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/PeerEventMessage.java
@@ -16,11 +16,11 @@ public class PeerEventMessage implements GnunetMessage.Body {
16 * either GNUNET_TESTBED_ET_PEER_START or GNUNET_TESTBED_ET_PEER_STOP. 16 * either GNUNET_TESTBED_ET_PEER_START or GNUNET_TESTBED_ET_PEER_STOP.
17 */ 17 */
18 @Int32 18 @Int32
19 int event_type; 19 public int eventType;
20 @Int32 20 @Int32
21 int host_id; 21 public int host_id;
22 @Int32 22 @Int32
23 int peer_id; 23 public int peer_id;
24 @Int64 24 @Int64
25 int operation_id; 25 public long operationId;
26} 26}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerGetInformationMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerGetInformationMessage.java
new file mode 100644
index 0000000..315e5eb
--- /dev/null
+++ b/src/main/java/org/gnunet/testbed/messages/PeerGetInformationMessage.java
@@ -0,0 +1,34 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.testbed.messages;
22
23import org.gnunet.construct.UInt32;
24import org.gnunet.construct.UInt64;
25import org.gnunet.construct.UnionCase;
26import org.gnunet.util.GnunetMessage;
27
28@UnionCase(476)
29public class PeerGetInformationMessage implements GnunetMessage.Body {
30 @UInt32
31 public int peerId;
32 @UInt64
33 public long operationId;
34}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java
new file mode 100644
index 0000000..b009f58
--- /dev/null
+++ b/src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java
@@ -0,0 +1,56 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.testbed.messages;
22
23import org.gnunet.construct.*;
24import org.gnunet.util.GnunetMessage;
25import org.gnunet.util.PeerIdentity;
26
27@UnionCase(477)
28public class PeerInformationMessage implements GnunetMessage.Body {
29 /**
30 * The testbed-internal id of the peer relevant to this
31 * information.
32 */
33 @UInt32
34 public int peerId;
35
36 /**
37 * Operation ID of the operation that created this event.
38 */
39 @UInt64
40 public long operationId;
41
42 /**
43 * Identity of the peer.
44 */
45 @NestedMessage
46 public PeerIdentity peerIdentity;
47
48 @UInt16
49 public int uncompressedConfigSize;
50
51 @UInt16
52 public int pading1;
53
54 @FillWith @UInt8
55 public byte[] compressedConfig;
56}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerReconfigureMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerReconfigureMessage.java
index 2c07d79..aac2c0a 100644
--- a/src/main/java/org/gnunet/testbed/messages/PeerReconfigureMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/PeerReconfigureMessage.java
@@ -1,8 +1,21 @@
1package org.gnunet.testbed.messages; 1package org.gnunet.testbed.messages;
2 2
3import org.gnunet.construct.*;
4import org.gnunet.util.GnunetMessage;
5
3/** 6/**
4 * Message sent from client to testing service to 7 * Message sent from client to testing service to
5 * reconfigure a (stopped) a peer. 8 * reconfigure a (stopped) a peer.
6 */ 9 */
7public class PeerReconfigureMessage { 10@UnionCase(465)
11public class PeerReconfigureMessage implements GnunetMessage.Body {
12 @UInt32
13 public int peerId;
14 @UInt64
15 public long operationId;
16 @UInt16
17 public int uncompressedConfigSize;
18 @FillWith
19 @UInt8
20 public byte[] compressedConfig;
8} 21}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerStartMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerStartMessage.java
index 2f8e4c2..71c220d 100644
--- a/src/main/java/org/gnunet/testbed/messages/PeerStartMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/PeerStartMessage.java
@@ -11,5 +11,5 @@ public class PeerStartMessage implements GnunetMessage.Body {
11 @UInt32 11 @UInt32
12 public int peer_id; 12 public int peer_id;
13 @UInt64 13 @UInt64
14 public int operation_id; 14 public long operation_id;
15} 15}
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerStopMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerStopMessage.java
index 8436531..cdf5cd5 100644
--- a/src/main/java/org/gnunet/testbed/messages/PeerStopMessage.java
+++ b/src/main/java/org/gnunet/testbed/messages/PeerStopMessage.java
@@ -11,5 +11,5 @@ public class PeerStopMessage implements GnunetMessage.Body {
11 @UInt32 11 @UInt32
12 public int peer_id; 12 public int peer_id;
13 @UInt64 13 @UInt64
14 public int operation_id; 14 public long operation_id;
15} 15}
diff --git a/src/main/java/org/gnunet/util/AbsoluteTime.java b/src/main/java/org/gnunet/util/AbsoluteTime.java
index 9d22d36..265abf5 100644
--- a/src/main/java/org/gnunet/util/AbsoluteTime.java
+++ b/src/main/java/org/gnunet/util/AbsoluteTime.java
@@ -266,4 +266,8 @@ public class AbsoluteTime implements Comparable<AbsoluteTime> {
266 public Date toDate() { 266 public Date toDate() {
267 return new Date(abs_value_us / 1000); 267 return new Date(abs_value_us / 1000);
268 } 268 }
269
270 public long getSeconds() {
271 return abs_value_us / (1000 * 1000);
272 }
269} 273}
diff --git a/src/main/java/org/gnunet/util/CryptoECC.java b/src/main/java/org/gnunet/util/CryptoECC.java
index c30dd0b..d27a2a4 100644
--- a/src/main/java/org/gnunet/util/CryptoECC.java
+++ b/src/main/java/org/gnunet/util/CryptoECC.java
@@ -24,13 +24,18 @@ import org.gnunet.construct.FixedSizeIntegerArray;
24import org.gnunet.construct.Message; 24import org.gnunet.construct.Message;
25 25
26import java.io.File; 26import java.io.File;
27import java.io.FileOutputStream;
27import java.io.IOError; 28import java.io.IOError;
28import java.io.IOException; 29import java.io.IOException;
29import java.math.BigInteger; 30import java.math.BigInteger;
30import java.nio.ByteBuffer; 31import java.nio.ByteBuffer;
31import java.nio.file.Files; 32import java.nio.file.Files;
33import java.nio.file.OpenOption;
34import java.nio.file.StandardOpenOption;
32import java.security.MessageDigest; 35import java.security.MessageDigest;
33import java.security.NoSuchAlgorithmException; 36import java.security.NoSuchAlgorithmException;
37import java.security.SecureRandom;
38import java.util.Random;
34 39
35/** 40/**
36 * Implementation of the Ed25519 public-key signature system. See http://ed25519.cr.yp.to/. 41 * Implementation of the Ed25519 public-key signature system. See http://ed25519.cr.yp.to/.
@@ -68,6 +73,19 @@ public class CryptoECC {
68 privateKey.d = data; 73 privateKey.d = data;
69 return privateKey; 74 return privateKey;
70 } 75 }
76
77 public static PrivateKey createRandom() {
78 PrivateKey privateKey = new PrivateKey();
79 privateKey.d = new byte[32];
80 SecureRandom r = new SecureRandom();
81 r.nextBytes(privateKey.d);
82 return privateKey;
83 }
84
85 public void write(String privKeyFilename) throws IOException {
86 File f = new File(privKeyFilename);
87 Files.write(f.toPath(), d, StandardOpenOption.CREATE_NEW);
88 }
71 } 89 }
72 90
73 /** 91 /**
@@ -97,6 +115,17 @@ public class CryptoECC {
97 public BigInteger[] asPoint() { 115 public BigInteger[] asPoint() {
98 return new BigInteger[]{decodeint(x), decodeint(y)}; 116 return new BigInteger[]{decodeint(x), decodeint(y)};
99 } 117 }
118
119 public static PublicKey fromString(String s) {
120 PublicKey pk = new PublicKey();
121 byte[] data = Strings.stringToData(s, 32);
122 if (null == data)
123 return null;
124 BigInteger[] point = decodepoint(data);
125 pk.x = encodeint(point[0]);
126 pk.y = encodeint(point[1]);
127 return pk;
128 }
100 } 129 }
101 130
102 /** 131 /**
@@ -124,6 +153,35 @@ public class CryptoECC {
124 System.arraycopy(s, 0, data, r.length, s.length); 153 System.arraycopy(s, 0, data, r.length, s.length);
125 return Strings.dataToString(data); 154 return Strings.dataToString(data);
126 } 155 }
156
157 public static Signature fromString(String s) {
158 Signature sig = new Signature();
159 sig.r = new byte[32];
160 sig.s = new byte[32];
161 byte[] data = Strings.stringToData(s, 64);
162 if (null == data) {
163 return null;
164 }
165 System.arraycopy(data, 0, sig.r, 0, 32);
166 System.arraycopy(data, 32, sig.s, 0, 32);
167 return sig;
168 }
169
170 /**
171 * Create a random signature that is invalid with
172 * very high probability.
173 *
174 * @return random signature, most probably invalid
175 */
176 public static Signature randomSignature() {
177 Random r = new Random();
178 Signature sig = new Signature();
179 sig.r = new byte[32];
180 sig.s = new byte[32];
181 r.nextBytes(sig.r);
182 r.nextBytes(sig.s);
183 return sig;
184 }
127 } 185 }
128 186
129 // curve parameter b 187 // curve parameter b
diff --git a/src/main/java/org/gnunet/util/HashCode.java b/src/main/java/org/gnunet/util/HashCode.java
index 0c2790f..2ae127d 100644
--- a/src/main/java/org/gnunet/util/HashCode.java
+++ b/src/main/java/org/gnunet/util/HashCode.java
@@ -91,4 +91,9 @@ public class HashCode implements Message {
91 public int hashCode() { 91 public int hashCode() {
92 return Arrays.hashCode(this.data); 92 return Arrays.hashCode(this.data);
93 } 93 }
94
95 @Override
96 public String toString() {
97 return Strings.dataToString(data);
98 }
94} \ No newline at end of file 99} \ No newline at end of file
diff --git a/src/main/java/org/gnunet/util/PeerIdentity.java b/src/main/java/org/gnunet/util/PeerIdentity.java
index 46a67cd..39da4cd 100644
--- a/src/main/java/org/gnunet/util/PeerIdentity.java
+++ b/src/main/java/org/gnunet/util/PeerIdentity.java
@@ -66,4 +66,10 @@ public class PeerIdentity implements Message {
66 public int hashCode() { 66 public int hashCode() {
67 return Arrays.hashCode(data); 67 return Arrays.hashCode(data);
68 } 68 }
69
70 public static PeerIdentity fromString(String value) {
71 PeerIdentity p = new PeerIdentity();
72 p.data = Strings.stringToData(value, p.data.length);
73 return (p.data == null) ? null : p;
74 }
69} 75}
diff --git a/src/main/java/org/gnunet/util/Program.java b/src/main/java/org/gnunet/util/Program.java
index 4884486..9ce1a44 100644
--- a/src/main/java/org/gnunet/util/Program.java
+++ b/src/main/java/org/gnunet/util/Program.java
@@ -177,8 +177,10 @@ public abstract class Program {
177 177
178 /** 178 /**
179 * Start the Program as the initial task of the Scheduler. 179 * Start the Program as the initial task of the Scheduler.
180 *
181 * @return the exit value of the scheduler
180 */ 182 */
181 public final void start() { 183 public final int start() {
182 Parser optParser = new Parser(this); 184 Parser optParser = new Parser(this);
183 unprocessedArgs = optParser.parse(args); 185 unprocessedArgs = optParser.parse(args);
184 186
@@ -204,6 +206,8 @@ public abstract class Program {
204 } 206 }
205 }); 207 });
206 } 208 }
209
210 return returnValue;
207 } 211 }
208 212
209 /** 213 /**
@@ -219,9 +223,9 @@ public abstract class Program {
219 /** 223 /**
220 * Override to implement the behavior of the Program. 224 * Override to implement the behavior of the Program.
221 */ 225 */
222 public abstract void run(); 226 protected abstract void run();
223 227
224 public final Configuration getConfiguration() { 228 protected final Configuration getConfiguration() {
225 return cfg; 229 return cfg;
226 } 230 }
227} 231}
diff --git a/src/main/java/org/gnunet/util/RunaboutMessageReceiver.java b/src/main/java/org/gnunet/util/RunaboutMessageReceiver.java
index 2a0f067..1de7ac0 100644
--- a/src/main/java/org/gnunet/util/RunaboutMessageReceiver.java
+++ b/src/main/java/org/gnunet/util/RunaboutMessageReceiver.java
@@ -20,6 +20,7 @@
20 20
21package org.gnunet.util; 21package org.gnunet.util;
22 22
23import org.gnunet.construct.ProtocolViolationException;
23import org.grothoff.Runabout; 24import org.grothoff.Runabout;
24 25
25/** 26/**
@@ -30,4 +31,12 @@ public abstract class RunaboutMessageReceiver extends Runabout implements Messag
30 public void process(GnunetMessage.Body msg) { 31 public void process(GnunetMessage.Body msg) {
31 this.visitAppropriate(msg); 32 this.visitAppropriate(msg);
32 } 33 }
34 public void handleUnknownMessageType(UnknownMessageBody unknownMessageBody) {
35 throw new ProtocolViolationException(
36 String.format("unexpected message type: %s", unknownMessageBody.id));
37 }
38 public void visit(UnknownMessageBody unknownMessageBody) {
39 // FIXME: UnknownMessageBody is ugly and should be removed entirely
40 handleUnknownMessageType(unknownMessageBody);
41 }
33} 42}
diff --git a/src/main/java/org/gnunet/util/Strings.java b/src/main/java/org/gnunet/util/Strings.java
index a35568a..f591cf0 100644
--- a/src/main/java/org/gnunet/util/Strings.java
+++ b/src/main/java/org/gnunet/util/Strings.java
@@ -32,8 +32,6 @@ public class Strings {
32 * GNUnet specific. It was chosen such that it only uses characters 32 * GNUnet specific. It was chosen such that it only uses characters
33 * in [0-9A-V], can be produced without complex arithmetics and uses a 33 * in [0-9A-V], can be produced without complex arithmetics and uses a
34 * small number of characters. 34 * small number of characters.
35 * Does not append 0-terminator, but returns a pointer to the place where
36 * it should be placed, if needed.
37 * 35 *
38 * returned string has length ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 bytes 36 * returned string has length ((size*8) + (((size*8) % 5) > 0 ? 5 - ((size*8) % 5) : 0)) / 5 bytes
39 * 37 *
@@ -75,7 +73,7 @@ public class Strings {
75 * 73 *
76 * @param string the string to decode 74 * @param string the string to decode
77 * @param outSize size of the output buffer 75 * @param outSize size of the output buffer
78 * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding 76 * @return the decoded data on success, null if result has the wrong encoding
79 */ 77 */
80 78
81 public static byte[] stringToData(String string, int outSize) { 79 public static byte[] stringToData(String string, int outSize) {
@@ -97,20 +95,20 @@ public class Strings {
97 shift = 0; 95 shift = 0;
98 } 96 }
99 if ((encoded_len + shift) / 5 != enclen) { 97 if ((encoded_len + shift) / 5 != enclen) {
100 throw new AssertionError(); 98 return null;
101 } 99 }
102 100
103 wpos = outSize; 101 wpos = outSize;
104 rpos = enclen; 102 rpos = enclen;
105 bits = (ret = getValue__(string.charAt((int) (--rpos)))) >> (5 - encoded_len % 5); 103 bits = (ret = getValue__(string.charAt((int) (--rpos)))) >> (5 - encoded_len % 5);
106 if (-1 == ret) { 104 if (-1 == ret) {
107 throw new AssertionError(); 105 return null;
108 } 106 }
109 while (wpos > 0) { 107 while (wpos > 0) {
110 assert rpos > 0; 108 assert rpos > 0;
111 bits = ((ret = getValue__(string.charAt((int) (--rpos)))) << vbit) | bits; 109 bits = ((ret = getValue__(string.charAt((int) (--rpos)))) << vbit) | bits;
112 if (-1 == ret) { 110 if (-1 == ret) {
113 throw new AssertionError(); 111 return null;
114 } 112 }
115 vbit += 5; 113 vbit += 5;
116 if (vbit >= 8) { 114 if (vbit >= 8) {
diff --git a/src/main/java/org/gnunet/voting/Ballot.java b/src/main/java/org/gnunet/voting/Ballot.java
new file mode 100644
index 0000000..49f1465
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/Ballot.java
@@ -0,0 +1,289 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.voting;
22
23import com.google.common.base.Joiner;
24import com.google.common.base.Optional;
25import com.google.common.collect.BiMap;
26import com.google.common.collect.HashBiMap;
27import com.google.common.collect.Maps;
28import org.gnunet.util.*;
29
30import java.security.MessageDigest;
31import java.security.NoSuchAlgorithmException;
32import java.util.*;
33import java.util.regex.Pattern;
34
35/**
36 * Public information about an election.
37 */
38public class Ballot {
39
40 String topic;
41 List<String> choices;
42 AbsoluteTime electionStartTime;
43 AbsoluteTime electionEndTime;
44 BiMap<String,PeerIdentity> authorities;
45 SortedMap<String,CryptoECC.Signature> registrationSigs;
46 CryptoECC.PublicKey caPub;
47 CryptoECC.PublicKey issuerPub;
48 CryptoECC.Signature issuerSig;
49 CryptoECC.PublicKey voter_pub;
50 CryptoECC.Signature permission;
51 CryptoECC.PublicKey voter_sig;
52 SortedMap<String,CryptoECC.Signature> vouchers;
53
54 /**
55 * Choice in plaintext.
56 * This field would be encrypted in a secure version.
57 */
58 int choiceId = -1;
59
60 /**
61 * Load a ballot from file.
62 *
63 * @throws InvalidBallotException
64 * @param filename
65 */
66 public Ballot(String filename) {
67 Configuration cfg = new Configuration();
68 cfg.parse(filename);
69 fillBallot(cfg);
70 }
71
72 public Ballot(Configuration cfg) {
73 fillBallot(cfg);
74 }
75
76 private void fillBallot(Configuration cfg) {
77 Optional<String> optTopic = cfg.getValueString("election", "TOPIC");
78 if (!optTopic.isPresent()) {
79 throw new InvalidBallotException("ballot has no topic");
80 }
81 topic = optTopic.get();
82 Optional<String> optChoices = cfg.getValueString("election", "CHOICES");
83 if (!optChoices.isPresent()) {
84 throw new InvalidBallotException("ballot has no choices");
85 }
86 choices = Arrays.asList(optChoices.get().split(Pattern.quote("//")));
87 if (choices.size() < 2) {
88 throw new InvalidBallotException("less than two choices present");
89 }
90 authorities = HashBiMap.create();
91 for (Map.Entry<String,String> e : cfg.getSection("authorities").entrySet()) {
92 String alias = e.getKey();
93 PeerIdentity peerIdentity = PeerIdentity.fromString(e.getValue());
94 if (peerIdentity == null) {
95 throw new InvalidBallotException(
96 String.format("authority %s has invalid peer identity", alias));
97 }
98 authorities.put(alias, peerIdentity);
99 }
100 if (authorities.size() < 1) {
101 throw new InvalidBallotException("ballot must specify at least one authority");
102 }
103 Optional<String> optCaPub = cfg.getValueString("election", "CA_PUB");
104 if (!optCaPub.isPresent()) {
105 throw new InvalidBallotException("no CA pub key given");
106 }
107 caPub = CryptoECC.PublicKey.fromString(optCaPub.get());
108 if (null == caPub) {
109 throw new InvalidBallotException("CA pub key invalid");
110 }
111 Optional<String> optIssuerPub = cfg.getValueString("election", "ISSUER_PUB");
112 if (optIssuerPub.isPresent()) {
113 issuerPub = CryptoECC.PublicKey.fromString(optIssuerPub.get());
114 Optional<String> optIssuerSig = cfg.getValueString("election", "ISSUER_SIG");
115 if (!optIssuerSig.isPresent()) {
116 throw new InvalidBallotException("issuer public key present, but no signature");
117 }
118 issuerSig = CryptoECC.Signature.fromString(optIssuerSig.get());
119 }
120 registrationSigs = new TreeMap<String, CryptoECC.Signature>();
121 for (Map.Entry<String,String> e : cfg.getSection("registration-signatures").entrySet()) {
122 CryptoECC.Signature sig = CryptoECC.Signature.fromString(e.getValue());
123 if (null == sig) {
124 throw new InvalidBallotException("registration signature has invalid format");
125 }
126 if (!authorities.containsKey(e.getKey())) {
127 throw new InvalidBallotException("ballot contains superfluous registration signature");
128 }
129 registrationSigs.put(e.getKey(), sig);
130 }
131 Optional<String> optChoiceId = cfg.getValueString("vote", "CHOICE_ID");
132 if (optChoiceId.isPresent()) {
133 choiceId = Integer.parseInt(optChoiceId.get());
134 if (choiceId < 0 || choiceId >= choices.size()) {
135 throw new InvalidBallotException("invalid choice in vote");
136 }
137 } else {
138 choiceId = -1;
139 }
140 }
141
142 public HashCode getBallotGuid() {
143 if (issuerSig == null) {
144 throw new InvalidBallotException("can't compute GUID of non-issued ballot");
145 }
146 MessageDigest digest;
147 try {
148 digest = MessageDigest.getInstance("SHA-512");
149 } catch (NoSuchAlgorithmException e) {
150 throw new RuntimeException("crypto algorithm required but not provided");
151 }
152 digest.update(topic.getBytes());
153 //digest.update(Longs.toByteArray(electionStartTime.getSeconds()));
154 //digest.update(Longs.toByteArray(electionEndTime.getSeconds()));
155 for (String choice : choices) {
156 digest.update(choice.getBytes());
157 }
158 for (SortedMap.Entry<String,PeerIdentity> x : authorities.entrySet()) {
159 digest.update(x.getKey().getBytes());
160 digest.update(x.getValue().data);
161 }
162 digest.update(issuerPub.x);
163 digest.update(issuerPub.y);
164 digest.update(caPub.x);
165 digest.update(caPub.y);
166 return new HashCode(digest.digest());
167 }
168
169 /**
170 * Encode the given choice permanently in the ballot.
171 *
172 * @param choice the choice to encode the ballot
173 * @param privateKey the private key to use for encoding
174 */
175 public void encodeChoice(String choice, CryptoECC.PrivateKey privateKey) {
176 choiceId = -1;
177 int i = 0;
178 for (String possibleChoice : choices) {
179 if (choice.equals(possibleChoice)) {
180 choiceId = i;
181 }
182 i++;
183 }
184 if (choiceId == -1) {
185 throw new InvalidBallotException(String.format("choice '%s' not valid", choice));
186 }
187 }
188
189 public Configuration toConfiguration() {
190 Configuration cfg = new Configuration();
191 cfg.setValueString("election", "TOPIC", topic);
192 cfg.setValueString("election", "CHOICES", Joiner.on("//").join(choices));
193 cfg.setValueString("election", "CA_PUB", caPub.toString());
194 for (Map.Entry<String, PeerIdentity> e : authorities.entrySet()) {
195 cfg.setValueString("authorities", e.getKey(), e.getValue().toString());
196 }
197 for (Map.Entry<String, CryptoECC.Signature> e : registrationSigs.entrySet()) {
198 cfg.setValueString("registration-signatures", e.getKey(), e.getValue().toString());
199 }
200 if (null != issuerPub) {
201 cfg.setValueString("election", "ISSUER_PUB", issuerPub.toString());
202 cfg.setValueString("election", "ISSUER_SIG", issuerSig.toString());
203 }
204 if (-1 != choiceId) {
205 cfg.setValueNumber("vote", "CHOICE_ID", choiceId);
206 }
207 return cfg;
208 }
209
210 public String serialize() {
211 return toConfiguration().serialize();
212 }
213
214 public String describe() {
215 StringBuilder buf = new StringBuilder();
216 buf.append("Topic: ");
217 buf.append("'");
218 buf.append(topic);
219 buf.append("'\n");
220 buf.append("Choices:\n");
221 for (int i = 0; i < choices.size(); i++) {
222 buf.append(""+(i+1));
223 buf.append(". '");
224 buf.append(choices.get(i));
225 buf.append("'\n");
226 }
227 buf.append("Authorities:\n");
228 for (Map.Entry<String, PeerIdentity> e : authorities.entrySet()) {
229 buf.append("'");
230 buf.append(e.getKey());
231 buf.append("', ");
232 buf.append(e.getValue().toString());
233 buf.append("\n");
234 }
235 if (issuerPub == null) {
236 buf.append("issue status: not issued\n");
237 } else {
238 buf.append("issue status: issued, GUID ");
239 buf.append(getBallotGuid().toString());
240 buf.append("\n");
241 }
242 if (!registrationSigs.isEmpty()) {
243 buf.append("ballot is registered with the following authorities:\n");
244 for (Map.Entry<String, CryptoECC.Signature> e : registrationSigs.entrySet()) {
245 buf.append(e.getKey());
246 buf.append(" ");
247 }
248 buf.append("\n");
249 }
250 else {
251 buf.append("ballot not registered\n");
252 }
253 if (choiceId != -1) {
254 buf.append("choice selected\n");
255 } else {
256 buf.append("no choice selected\n");
257 }
258 return buf.toString();
259 }
260
261 public List<PeerIdentity> getRemainingSubmitAuthorities() {
262 // FIXME: only return remaining authorities
263 return new ArrayList<PeerIdentity>(authorities.values());
264 }
265
266
267 public List<PeerIdentity> getRemainingRegisterAuthorities() {
268 LinkedList<PeerIdentity> remaining = new LinkedList<PeerIdentity>();
269 for (SortedMap.Entry<String,PeerIdentity> x : authorities.entrySet()) {
270 if (!registrationSigs.containsKey(x.getKey()))
271 remaining.add(x.getValue());
272 }
273 return remaining;
274 }
275
276 public void issue(CryptoECC.PrivateKey privateKey) {
277 issuerPub = CryptoECC.computePublicKey(privateKey);
278 issuerSig = CryptoECC.sign(getBallotGuid().data, privateKey, issuerPub);
279 }
280
281 public void addRegistrationSignature(PeerIdentity currentAuthority, CryptoECC.Signature registrationSignature) {
282 String alias = authorities.inverse().get(currentAuthority);
283 registrationSigs.put(alias, registrationSignature);
284 }
285
286 public List<PeerIdentity> getAuthorities() {
287 return new ArrayList<PeerIdentity>(authorities.values());
288 }
289}
diff --git a/src/main/java/org/gnunet/voting/BallotTool.java b/src/main/java/org/gnunet/voting/BallotTool.java
index 48f252f..619afa5 100644
--- a/src/main/java/org/gnunet/voting/BallotTool.java
+++ b/src/main/java/org/gnunet/voting/BallotTool.java
@@ -27,8 +27,10 @@ import com.google.common.io.Files;
27import com.google.common.io.OutputSupplier; 27import com.google.common.io.OutputSupplier;
28import org.gnunet.mesh.Mesh; 28import org.gnunet.mesh.Mesh;
29import org.gnunet.mesh.MeshRunabout; 29import org.gnunet.mesh.MeshRunabout;
30import org.gnunet.mesh.TunnelEndHandler;
30import org.gnunet.util.Configuration; 31import org.gnunet.util.Configuration;
31import org.gnunet.util.CryptoECC; 32import org.gnunet.util.CryptoECC;
33import org.gnunet.util.PeerIdentity;
32import org.gnunet.util.Program; 34import org.gnunet.util.Program;
33import org.gnunet.util.getopt.Argument; 35import org.gnunet.util.getopt.Argument;
34import org.gnunet.util.getopt.ArgumentAction; 36import org.gnunet.util.getopt.ArgumentAction;
@@ -41,6 +43,7 @@ import java.io.FileOutputStream;
41import java.io.IOException; 43import java.io.IOException;
42import java.io.InputStream; 44import java.io.InputStream;
43import java.nio.charset.Charset; 45import java.nio.charset.Charset;
46import java.util.List;
44import java.util.regex.Pattern; 47import java.util.regex.Pattern;
45 48
46/** 49/**
@@ -71,6 +74,13 @@ public class BallotTool {
71 boolean register = false; 74 boolean register = false;
72 75
73 @Argument( 76 @Argument(
77 shortname = "i",
78 longname = "issue",
79 action = ArgumentAction.SET,
80 description = "sign the ballot as issuer")
81 boolean issue = false;
82
83 @Argument(
74 shortname = "x", 84 shortname = "x",
75 longname = "select", 85 longname = "select",
76 action = ArgumentAction.STORE_STRING, 86 action = ArgumentAction.STORE_STRING,
@@ -99,6 +109,21 @@ public class BallotTool {
99 description = "write a template ballot to the give ballot file") 109 description = "write a template ballot to the give ballot file")
100 boolean template = false; 110 boolean template = false;
101 111
112 @Argument(
113 shortname = "g",
114 longname = "gen-key",
115 action = ArgumentAction.SET,
116 description = "generate a private key")
117 boolean genKey = false;
118
119 @Argument(
120 shortname = "P",
121 longname = "print-key",
122 action = ArgumentAction.SET,
123 description = "print the public key for the private key")
124 boolean printKey = false;
125
126
102 @Override 127 @Override
103 protected String makeHelpText() { 128 protected String makeHelpText() {
104 return "gnunet-ballot [OPTIONS]... BALLOT [PRIVKEYFILE]\n" + 129 return "gnunet-ballot [OPTIONS]... BALLOT [PRIVKEYFILE]\n" +
@@ -120,7 +145,7 @@ public class BallotTool {
120 } 145 }
121 } 146 }
122 147
123 private void runRegister(String ballotFilename, String privKeyFilename) { 148 private void runIssue(String ballotFilename, String privKeyFilename) {
124 File bf = new File(ballotFilename); 149 File bf = new File(ballotFilename);
125 if (!bf.exists()) { 150 if (!bf.exists()) {
126 System.err.println("ballot file does not exist"); 151 System.err.println("ballot file does not exist");
@@ -131,26 +156,18 @@ public class BallotTool {
131 System.err.println("private-key file does not exist"); 156 System.err.println("private-key file does not exist");
132 return; 157 return;
133 } 158 }
134 Configuration ballot = new Configuration(); 159 Ballot b = new Ballot(ballotFilename);
135 ballot.parse(ballotFilename);
136 CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.fromFile(privKeyFilename); 160 CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.fromFile(privKeyFilename);
137 if (privateKey == null) { 161 if (privateKey == null) {
138 System.err.println("keyfile invalid"); 162 System.err.println("keyfile invalid");
139 return; 163 return;
140 } 164 }
141 CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey); 165 b.issue(privateKey);
142 ballot.setValueString("election", "ISSUER_PUB", publicKey.toString());
143 String sigData = ballot.serialize("election", "authorities");
144 CryptoECC.Signature sig = CryptoECC.sign(sigData.getBytes(Charsets.UTF_8), privateKey, publicKey);
145 ballot.setValueString("registration-issuer", "SIGNATURE", sig.toString());
146 String b = ballot.serialize();
147 try { 166 try {
148 Files.write(b, bf, Charsets.UTF_8); 167 Files.write(b.serialize(), bf, Charsets.UTF_8);
149 } catch (IOException e) { 168 } catch (IOException e) {
150 System.err.println("can not write to ballot file"); 169 System.err.println("could not write ballot file: " + e.getMessage());
151 return;
152 } 170 }
153 System.out.println("ballot registered");
154 } 171 }
155 172
156 public void runSelect(String ballotFilename, String privKeyFilename, String choice) { 173 public void runSelect(String ballotFilename, String privKeyFilename, String choice) {
@@ -164,30 +181,13 @@ public class BallotTool {
164 System.err.println("private-key file does not exist"); 181 System.err.println("private-key file does not exist");
165 return; 182 return;
166 } 183 }
167 Configuration ballot = new Configuration();
168 ballot.parse(ballotFilename);
169 CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.fromFile(privKeyFilename); 184 CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.fromFile(privKeyFilename);
170 if (privateKey == null) { 185 if (privateKey == null) {
171 System.err.println("keyfile invalid"); 186 System.err.println("keyfile invalid");
172 return; 187 return;
173 } 188 }
174 CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey); 189 Ballot ballot = new Ballot(ballotFilename);
175 String choicesStr = ballot.getValueString("election", "CHOICES").get(); 190 ballot.encodeChoice(choice, privateKey);
176 String[] choices = choicesStr.trim().split(Pattern.quote("//"));
177 choice = choice.trim();
178 boolean found = false;
179 for (String possibleChoice : choices) {
180 if (possibleChoice.trim().equals(choice))
181 found = true;
182 }
183 if (!found) {
184 System.err.println("choice invalid");
185 return;
186 }
187 CryptoECC.Signature sig = CryptoECC.sign(choice.getBytes(Charsets.UTF_8), privateKey, publicKey);
188 ballot.setValueString("vote", "CHOICE_PLAIN", choice);
189 ballot.setValueString("vote", "PUB", publicKey.toString());
190 ballot.setValueString("vote", "SIG", sig.toString());
191 try { 191 try {
192 Files.write(ballot.serialize(), bf, Charsets.UTF_8); 192 Files.write(ballot.serialize(), bf, Charsets.UTF_8);
193 } catch (IOException e) { 193 } catch (IOException e) {
@@ -197,42 +197,49 @@ public class BallotTool {
197 System.out.println("vote written to ballot file"); 197 System.out.println("vote written to ballot file");
198 } 198 }
199 199
200 public void runSubmit(String ballotFilename) { 200 public void runPermission(String ballotFilename, String privKeyFilename) {
201 class SubmitMessageReceiver extends MeshRunabout {
202 public void visit(SubmitResponseMessage m) {
203 // FIXME ...
204 }
205 }
206 File bf = new File(ballotFilename);
207 if (!bf.exists()) {
208 System.err.println("ballot file does not exist");
209 return;
210 }
211 Configuration ballot = new Configuration();
212 ballot.parse(ballotFilename);
213 Mesh mesh = new Mesh(getConfiguration(), null, null, new SubmitMessageReceiver());
214 Mesh.Tunnel<Void> t = mesh.createTunnel(null, CertificateAuthorityService.MESH_PORT, true, true, null);
215 SubmitMessage m = new SubmitMessage();
216 m.ballot = ballot.toString();
217 t.send(m);
218 // FIXME ...
219 }
220
221 public void runQuery(String ballotFilename) {
222 201
223 } 202 }
224 203
225 204 public void runGenKey(String privKeyFilename) {
226 public void runPermission(String ballotFilename, String privKeyFilename) { 205 File kf = new File(privKeyFilename);
227 206 if (kf.exists()) {
207 System.err.println("private key file already exists, not overwriting");
208 return;
209 }
210 CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.createRandom();
211 try {
212 privateKey.write(privKeyFilename);
213 } catch (IOException e) {
214 System.err.println("can't write to key file: " + e.getMessage());
215 }
228 } 216 }
229 217
218 public void runPrintKey(String privKeyFilename) {
219 File kf = new File(privKeyFilename);
220 if (!kf.exists()) {
221 System.err.println("key file does not exist");
222 return;
223 }
224 CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.fromFile(privKeyFilename);
225 if (privateKey == null) {
226 System.err.println("key invalid");
227 return;
228 }
229 CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey);
230 System.out.println(publicKey.toString());
231 }
230 232
231 public void runVerify(String ballotFilename) { 233 public void runVerify(String ballotFilename) {
232 System.err.print("not implemented"); 234 File bf = new File(ballotFilename);
235 if (!bf.exists()) {
236 System.err.println("ballot file does not exist");
237 return;
238 }
239 Ballot ballot = new Ballot(ballotFilename);
240 System.out.print(ballot.describe());
233 } 241 }
234 242
235
236 @Override 243 @Override
237 public void run() { 244 public void run() {
238 if (template) { 245 if (template) {
@@ -245,11 +252,20 @@ public class BallotTool {
245 } 252 }
246 253
247 if (register) { 254 if (register) {
255 if (this.unprocessedArgs.length != 1) {
256 System.err.println("-r/--register requires exactly one positional argument");
257 return;
258 }
259 RegisterCommand c = new RegisterCommand(getConfiguration(), unprocessedArgs[0]);
260 c.run();
261 return;
262 }
263 if (issue) {
248 if (this.unprocessedArgs.length != 2) { 264 if (this.unprocessedArgs.length != 2) {
249 System.err.println("-r/--register requires exactly two positional arguments"); 265 System.err.println("-i/--issue requires exactly two positional arguments");
250 return; 266 return;
251 } 267 }
252 runRegister(unprocessedArgs[0], unprocessedArgs[1]); 268 runIssue(unprocessedArgs[0], unprocessedArgs[1]);
253 return; 269 return;
254 } 270 }
255 if (select != null) { 271 if (select != null) {
@@ -265,7 +281,8 @@ public class BallotTool {
265 System.err.println("-s/--submit requires exactly one positional argument"); 281 System.err.println("-s/--submit requires exactly one positional argument");
266 return; 282 return;
267 } 283 }
268 runSubmit(unprocessedArgs[0]); 284 SubmitCommand c = new SubmitCommand(getConfiguration(), unprocessedArgs[0]);
285 c.run();
269 return; 286 return;
270 } 287 }
271 if (verify) { 288 if (verify) {
@@ -281,7 +298,8 @@ public class BallotTool {
281 System.err.println("-q/--query requires exactly one positional argument"); 298 System.err.println("-q/--query requires exactly one positional argument");
282 return; 299 return;
283 } 300 }
284 runQuery(unprocessedArgs[0]); 301 QueryCommand c = new QueryCommand(getConfiguration(), unprocessedArgs[0]);
302 c.run();
285 return; 303 return;
286 } 304 }
287 if (permission) { 305 if (permission) {
@@ -289,9 +307,25 @@ public class BallotTool {
289 System.err.println("-p/--permission requires exactly two positional arguments"); 307 System.err.println("-p/--permission requires exactly two positional arguments");
290 return; 308 return;
291 } 309 }
292 runPermission(unprocessedArgs[0], unprocessedArgs[1]); 310 PermissionCommand c = new PermissionCommand(getConfiguration(),
311 unprocessedArgs[0], unprocessedArgs[1]);
312 c.run();
293 return; 313 return;
294 } 314 }
315 if (genKey) {
316 if (this.unprocessedArgs.length != 1) {
317 System.err.println("-g/--gen-key requires exactly one positional argument");
318 return;
319 }
320 runGenKey(unprocessedArgs[0]);
321 }
322 if (printKey) {
323 if (this.unprocessedArgs.length != 1) {
324 System.err.println("-P/--print-key requires exactly one positional argument");
325 return;
326 }
327 runPrintKey(unprocessedArgs[0]);
328 }
295 } 329 }
296 }.start(); 330 }.start();
297 331
diff --git a/src/main/java/org/gnunet/voting/InvalidBallotException.java b/src/main/java/org/gnunet/voting/InvalidBallotException.java
new file mode 100644
index 0000000..3f74f98
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/InvalidBallotException.java
@@ -0,0 +1,30 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.voting;
22
23/**
24 * Exception thrown when a ballot contains insufficient or invalid data.
25 */
26public class InvalidBallotException extends RuntimeException {
27 public InvalidBallotException(String msg) {
28 super(msg);
29 }
30}
diff --git a/src/main/java/org/gnunet/voting/PermissionCommand.java b/src/main/java/org/gnunet/voting/PermissionCommand.java
new file mode 100644
index 0000000..7e73dbd
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/PermissionCommand.java
@@ -0,0 +1,132 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/*
22 This file is part of GNUnet.
23 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
24
25 GNUnet is free software; you can redistribute it and/or modify
26 it under the terms of the GNU General Public License as published
27 by the Free Software Foundation; either version 3, or (at your
28 option) any later version.
29
30 GNUnet is distributed in the hope that it will be useful, but
31 WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 General Public License for more details.
34
35 You should have received a copy of the GNU General Public License
36 along with GNUnet; see the file COPYING. If not, write to the
37 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
38 Boston, MA 02111-1307, USA.
39 */
40
41/*
42 This file is part of GNUnet.
43 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
44
45 GNUnet is free software; you can redistribute it and/or modify
46 it under the terms of the GNU General Public License as published
47 by the Free Software Foundation; either version 3, or (at your
48 option) any later version.
49
50 GNUnet is distributed in the hope that it will be useful, but
51 WITHOUT ANY WARRANTY; without even the implied warranty of
52 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53 General Public License for more details.
54
55 You should have received a copy of the GNU General Public License
56 along with GNUnet; see the file COPYING. If not, write to the
57 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
58 Boston, MA 02111-1307, USA.
59 */
60
61package org.gnunet.voting;
62
63
64import org.gnunet.mesh.Mesh;
65import org.gnunet.mesh.MeshRunabout;
66import org.gnunet.mesh.TunnelEndHandler;
67import org.gnunet.util.Configuration;
68import org.gnunet.util.PeerIdentity;
69import org.gnunet.voting.messages.QueryFailureMessage;
70import org.gnunet.voting.messages.QueryMessage;
71import org.gnunet.voting.messages.QueryResponseMessage;
72
73import java.io.File;
74import java.util.List;
75import java.util.Random;
76
77public class PermissionCommand extends MeshRunabout implements TunnelEndHandler {
78 private final String ballotFilename;
79 private Ballot ballot;
80 private final Configuration cfg;
81 private Mesh mesh;
82 private Mesh.Tunnel<Void> tunnel;
83 private boolean submitted = false;
84
85 @Override
86 public void onTunnelEnd(Mesh.Tunnel tunnel) {
87 if (!submitted)
88 throw new AssertionError();
89 }
90
91 public void visit(QueryResponseMessage m) {
92 submitted = true;
93 if (m.results.length != ballot.choices.size()) {
94 System.out.println("failure to query result: malformed response");
95 } else {
96 System.out.println("got results:");
97 for (int i = 0; i < m.results.length; i++) {
98 System.out.println("'" + ballot.choices.get(i) + "': " + m.results[i]);
99 }
100 }
101
102 tunnel.destroy();
103 mesh.destroy();
104 }
105
106
107 public void visit(QueryFailureMessage m) {
108 submitted = true;
109 System.out.println("failure to query result: authority refused");
110 tunnel.destroy();
111 mesh.destroy();
112 }
113
114 public PermissionCommand(Configuration cfg, String ballotFilename, String pubKeyString) {
115 this.cfg = cfg;
116 this.ballotFilename = ballotFilename;
117 }
118
119 public void run() {
120 File bf = new File(ballotFilename);
121 if (!bf.exists()) {
122 System.err.println("ballot file does not exist");
123 return;
124 }
125 ballot = new Ballot(ballotFilename);
126
127 Random r = new Random();
128 mesh = new Mesh(cfg, this, this);
129 tunnel = mesh.createTunnel(null /* FIXME */, CertificateAuthorityService.MESH_PORT, true, true, null);
130 //tunnel.send(m);
131 }
132}
diff --git a/src/main/java/org/gnunet/voting/QueryCommand.java b/src/main/java/org/gnunet/voting/QueryCommand.java
new file mode 100644
index 0000000..5ab7acb
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/QueryCommand.java
@@ -0,0 +1,120 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/*
22 This file is part of GNUnet.
23 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
24
25 GNUnet is free software; you can redistribute it and/or modify
26 it under the terms of the GNU General Public License as published
27 by the Free Software Foundation; either version 3, or (at your
28 option) any later version.
29
30 GNUnet is distributed in the hope that it will be useful, but
31 WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 General Public License for more details.
34
35 You should have received a copy of the GNU General Public License
36 along with GNUnet; see the file COPYING. If not, write to the
37 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
38 Boston, MA 02111-1307, USA.
39 */
40
41package org.gnunet.voting;
42
43
44import org.gnunet.mesh.Mesh;
45import org.gnunet.mesh.MeshRunabout;
46import org.gnunet.mesh.TunnelEndHandler;
47import org.gnunet.util.Configuration;
48import org.gnunet.util.PeerIdentity;
49import org.gnunet.voting.messages.QueryFailureMessage;
50import org.gnunet.voting.messages.QueryMessage;
51import org.gnunet.voting.messages.QueryResponseMessage;
52
53import java.io.File;
54import java.util.List;
55import java.util.Random;
56
57public class QueryCommand extends MeshRunabout implements TunnelEndHandler {
58 private final String ballotFilename;
59 private Ballot ballot;
60 private final Configuration cfg;
61 private Mesh mesh;
62 private Mesh.Tunnel<Void> tunnel;
63 private boolean submitted = false;
64
65 @Override
66 public void onTunnelEnd(Mesh.Tunnel tunnel) {
67 if (!submitted)
68 throw new AssertionError();
69 }
70
71 public void visit(QueryResponseMessage m) {
72 submitted = true;
73 if (m.results.length != ballot.choices.size()) {
74 System.out.println("failure to query result: malformed response");
75 } else {
76 System.out.println("got results:");
77 for (int i = 0; i < m.results.length; i++) {
78 System.out.println("'" + ballot.choices.get(i) + "': " + m.results[i]);
79 }
80 }
81
82 tunnel.destroy();
83 mesh.destroy();
84 }
85
86
87 public void visit(QueryFailureMessage m) {
88 submitted = true;
89 System.out.println("failure to query result: authority refused");
90 tunnel.destroy();
91 mesh.destroy();
92 }
93
94 public QueryCommand(Configuration cfg, String ballotFilename) {
95 this.cfg = cfg;
96 this.ballotFilename = ballotFilename;
97 }
98
99 public void run() {
100 File bf = new File(ballotFilename);
101 if (!bf.exists()) {
102 System.err.println("ballot file does not exist");
103 return;
104 }
105 ballot = new Ballot(ballotFilename);
106 List<PeerIdentity> remainingAuthorities = ballot.getAuthorities();
107 if (remainingAuthorities.isEmpty()) {
108 System.err.println("no authorities available");
109 return;
110 }
111 Random r = new Random();
112 PeerIdentity authority = remainingAuthorities.get(r.nextInt(remainingAuthorities.size()));
113 System.out.println("querying authority" + authority.toString());
114 mesh = new Mesh(cfg, this, this);
115 tunnel = mesh.createTunnel(authority, TallyAuthorityDaemon.MESH_PORT, true, true, null);
116 QueryMessage m = new QueryMessage();
117 m.ballotGUID = ballot.getBallotGuid();
118 tunnel.send(m);
119 }
120}
diff --git a/src/main/java/org/gnunet/voting/RegisterCommand.java b/src/main/java/org/gnunet/voting/RegisterCommand.java
new file mode 100644
index 0000000..f9d4c4d
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/RegisterCommand.java
@@ -0,0 +1,119 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/*
22 This file is part of GNUnet.
23 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
24
25 GNUnet is free software; you can redistribute it and/or modify
26 it under the terms of the GNU General Public License as published
27 by the Free Software Foundation; either version 3, or (at your
28 option) any later version.
29
30 GNUnet is distributed in the hope that it will be useful, but
31 WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 General Public License for more details.
34
35 You should have received a copy of the GNU General Public License
36 along with GNUnet; see the file COPYING. If not, write to the
37 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
38 Boston, MA 02111-1307, USA.
39 */
40
41package org.gnunet.voting;
42
43
44import com.google.common.base.Charsets;
45import com.google.common.io.Files;
46import org.gnunet.mesh.Mesh;
47import org.gnunet.mesh.MeshRunabout;
48import org.gnunet.mesh.TunnelEndHandler;
49import org.gnunet.testbed.CompressedConfig;
50import org.gnunet.util.Configuration;
51import org.gnunet.util.PeerIdentity;
52import org.gnunet.voting.messages.BallotRegisterRequestMessage;
53import org.gnunet.voting.messages.BallotRegisterRespondMessage;
54import org.gnunet.voting.messages.SubmitMessage;
55import org.gnunet.voting.messages.SubmitResponseMessage;
56
57import java.io.File;
58import java.io.IOException;
59import java.util.List;
60import java.util.Random;
61
62public class RegisterCommand extends MeshRunabout implements TunnelEndHandler {
63 private final String ballotFilename;
64 private Ballot ballot;
65 private final Configuration cfg;
66 private Mesh mesh;
67 private Mesh.Tunnel<Void> tunnel;
68 private boolean submitted = false;
69 private PeerIdentity currentAuthority;
70
71 @Override
72 public void onTunnelEnd(Mesh.Tunnel tunnel) {
73 if (!submitted)
74 throw new AssertionError();
75 }
76
77 public void visit(BallotRegisterRespondMessage m) {
78 submitted = true;
79 System.out.println("vote successfully registered");
80 ballot.addRegistrationSignature(currentAuthority, m.registrationSignature);
81 try {
82 Files.write(ballot.serialize(), new File(ballotFilename), Charsets.UTF_8);
83 } catch (IOException e) {
84 System.out.println("could not write ballot file");
85 return;
86 }
87 tunnel.destroy();
88 mesh.destroy();
89 }
90
91 public RegisterCommand(Configuration cfg, String ballotFilename) {
92 this.cfg = cfg;
93 this.ballotFilename = ballotFilename;
94 }
95
96 public void run() {
97 File bf = new File(ballotFilename);
98 if (!bf.exists()) {
99 System.err.println("ballot file does not exist");
100 return;
101 }
102 ballot = new Ballot(ballotFilename);
103
104 List<PeerIdentity> remainingAuthorities = ballot.getRemainingRegisterAuthorities();
105 if (remainingAuthorities.isEmpty()) {
106 System.err.println("all authorities already received the ballot");
107 return;
108 }
109 Random r = new Random();
110 currentAuthority = remainingAuthorities.get(r.nextInt(remainingAuthorities.size()));
111 System.out.println("registering ballot with authority " + currentAuthority.toString());
112 mesh = new Mesh(cfg, this, this);
113 tunnel = mesh.createTunnel(currentAuthority, TallyAuthorityDaemon.MESH_PORT, true, true, null);
114 BallotRegisterRequestMessage m = new BallotRegisterRequestMessage();
115 CompressedConfig ccfg = new CompressedConfig(ballot.toConfiguration());
116 m.compressedBallotConfig = ccfg.compressed_data;
117 tunnel.send(m);
118 }
119}
diff --git a/src/main/java/org/gnunet/voting/SubmitCommand.java b/src/main/java/org/gnunet/voting/SubmitCommand.java
new file mode 100644
index 0000000..d00ea69
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/SubmitCommand.java
@@ -0,0 +1,84 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.voting;
22
23
24import org.gnunet.mesh.Mesh;
25import org.gnunet.mesh.MeshRunabout;
26import org.gnunet.mesh.TunnelEndHandler;
27import org.gnunet.util.Configuration;
28import org.gnunet.util.PeerIdentity;
29import org.gnunet.voting.messages.SubmitMessage;
30import org.gnunet.voting.messages.SubmitResponseMessage;
31
32import java.io.File;
33import java.util.List;
34import java.util.Random;
35
36public class SubmitCommand extends MeshRunabout implements TunnelEndHandler {
37 private final String ballotFilename;
38 private Ballot ballot;
39 private final Configuration cfg;
40 private Mesh mesh;
41 private Mesh.Tunnel<Void> tunnel;
42 private boolean submitted = false;
43
44 @Override
45 public void onTunnelEnd(Mesh.Tunnel tunnel) {
46 if (!submitted)
47 throw new AssertionError();
48 }
49
50 public void visit(SubmitResponseMessage m) {
51 submitted = true;
52 System.out.println("vote successfully submitted");
53 tunnel.destroy();
54 mesh.destroy();
55 }
56
57 public SubmitCommand(Configuration cfg, String ballotFilename) {
58 this.cfg = cfg;
59 this.ballotFilename = ballotFilename;
60 }
61
62 public void run() {
63 File bf = new File(ballotFilename);
64 if (!bf.exists()) {
65 System.err.println("ballot file does not exist");
66 return;
67 }
68 ballot = new Ballot(ballotFilename);
69 List<PeerIdentity> remainingAuthorities = ballot.getRemainingSubmitAuthorities();
70 if (remainingAuthorities.isEmpty()) {
71 System.err.println("all authorities already received the ballot");
72 return;
73 }
74 Random r = new Random();
75 PeerIdentity authority = remainingAuthorities.get(r.nextInt(remainingAuthorities.size()));
76 System.out.println("submitting to authority" + authority.toString());
77 mesh = new Mesh(cfg, null, this);
78 tunnel = mesh.createTunnel(authority, TallyAuthorityDaemon.MESH_PORT, true, true, null);
79 SubmitMessage m = new SubmitMessage();
80 m.ballotGuid = ballot.getBallotGuid();
81 m.choiceId = ballot.choiceId;
82 tunnel.send(m);
83 }
84}
diff --git a/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java b/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java
new file mode 100644
index 0000000..a74d175
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java
@@ -0,0 +1,116 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20package org.gnunet.voting;
21
22
23import com.google.common.collect.Maps;
24import org.gnunet.mesh.Mesh;
25import org.gnunet.mesh.MeshRunabout;
26import org.gnunet.testbed.CompressedConfig;
27import org.gnunet.util.*;
28import org.gnunet.voting.messages.*;
29import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import java.util.*;
33
34public class TallyAuthorityDaemon extends Program {
35 private static final Logger logger = LoggerFactory
36 .getLogger(TallyAuthorityDaemon.class);
37
38 public static final int MESH_PORT = 1002;
39 private Mesh mesh;
40
41 private HashMap<HashCode, ElectionState> elections = Maps.newHashMap();
42
43 class ElectionState {
44 Ballot ballot;
45 /**
46 * Set of voters that have submitted their ballot.
47 */
48 Set<CryptoECC.PublicKey> voters = new HashSet<CryptoECC.PublicKey>();
49
50 /**
51 * Maping from choice to number of votes for that choice.
52 */
53 int[] tally;
54 }
55
56
57 private class TallyMeshReceiver extends MeshRunabout {
58 public void visit(SubmitMessage m) {
59 ElectionState electionState = elections.get(m.ballotGuid);
60 if (null == electionState) {
61 return;
62 }
63 if (m.choiceId < 0 || m.choiceId >= electionState.tally.length) {
64 return;
65 }
66 electionState.tally[m.choiceId] += 1;
67 SubmitResponseMessage rm = new SubmitResponseMessage();
68 getSender().send(rm);
69 getSender().receiveDone();
70 }
71
72 public void visit(BallotRegisterRequestMessage m) {
73 logger.info("ballot register requested");
74
75 CompressedConfig ccfg = new CompressedConfig(m.compressedBallotConfig);
76 Ballot b = new Ballot(ccfg.decompress());
77 ElectionState electionState = new ElectionState();
78 electionState.tally = new int[b.choices.size()];
79 electionState.ballot = b;
80 elections.put(b.getBallotGuid(), electionState);
81 BallotRegisterRespondMessage rm = new BallotRegisterRespondMessage();
82 rm.registrationSignature = CryptoECC.Signature.randomSignature();
83 getSender().send(rm);
84 getSender().receiveDone();
85 }
86
87 public void visit(QueryMessage m) {
88 ElectionState electionState = elections.get(m.ballotGUID);
89 if (null == electionState) {
90 QueryFailureMessage rm = new QueryFailureMessage();
91 getSender().send(rm);
92
93 } else {
94 QueryResponseMessage rm = new QueryResponseMessage();
95 rm.results = electionState.tally;
96 getSender().send(rm);
97 }
98 getSender().receiveDone();
99 }
100 }
101
102 public TallyAuthorityDaemon(String[] args) {
103 super(args);
104 }
105
106 public static void main(String[] args) {
107 TallyAuthorityDaemon daemon = new TallyAuthorityDaemon(args);
108 daemon.start();
109 }
110
111 @Override
112 public void run() {
113 logger.info("running tally daemon");
114 mesh = new Mesh(getConfiguration(), null, null, new TallyMeshReceiver(), MESH_PORT);
115 }
116}
diff --git a/src/main/java/org/gnunet/voting/TallyAuthorityService.java b/src/main/java/org/gnunet/voting/TallyAuthorityService.java
deleted file mode 100644
index 2170cb2..0000000
--- a/src/main/java/org/gnunet/voting/TallyAuthorityService.java
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20package org.gnunet.voting;
21
22
23import com.google.common.collect.Maps;
24import org.gnunet.mesh.Mesh;
25import org.gnunet.mesh.MeshRunabout;
26import org.gnunet.util.CryptoECC;
27import org.gnunet.util.RelativeTime;
28import org.gnunet.util.Service;
29import org.gnunet.voting.messages.BallotRegisterRequestMessage;
30import org.gnunet.voting.messages.CertificateRequestMessage;
31import org.gnunet.voting.messages.QueryResultMessage;
32import org.gnunet.voting.messages.SubmitMessage;
33
34import java.util.HashSet;
35import java.util.Map;
36import java.util.Set;
37
38public class TallyAuthorityService extends Service {
39 public static final int MESH_PORT = 1002;
40 private Mesh mesh;
41
42
43 private class ElectionState {
44 /**
45 * Set of voters that have submitted their ballot.
46 */
47 private Set<CryptoECC.PublicKey> voters = new HashSet<CryptoECC.PublicKey>();
48
49 /**
50 * Maping from choice to number of votes for that choice.
51 */
52 private Map<String,Integer> tally = Maps.newHashMap();
53 }
54
55
56 private class TallyMeshReceiver extends MeshRunabout {
57 public void visit(SubmitMessage m) {
58 // TODO: count!
59 }
60 public void visit(BallotRegisterRequestMessage m) {
61 // TODO ...
62 }
63 public void visit(QueryResultMessage m) {
64
65 }
66 }
67
68 public TallyAuthorityService(String[] args) {
69 super("voting-tally", RelativeTime.FOREVER, true, args);
70 }
71
72 public static void main(String[] args) {
73 CertificateAuthorityService service = new CertificateAuthorityService(args);
74 service.start();
75 }
76
77 @Override
78 public void run() {
79 mesh = new Mesh(getConfiguration(), null, null, new TallyMeshReceiver(), MESH_PORT);
80 }
81}
diff --git a/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java b/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java
index 3214187..95a7c2f 100644
--- a/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java
+++ b/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java
@@ -1,6 +1,11 @@
1package org.gnunet.voting.messages; 1package org.gnunet.voting.messages;
2 2
3import org.gnunet.construct.IntegerFill;
4import org.gnunet.construct.UnionCase;
3import org.gnunet.util.GnunetMessage; 5import org.gnunet.util.GnunetMessage;
4 6
7@UnionCase(42001)
5public class BallotRegisterRequestMessage implements GnunetMessage.Body { 8public class BallotRegisterRequestMessage implements GnunetMessage.Body {
9 @IntegerFill(signed = false, bitSize = 8)
10 public byte[] compressedBallotConfig;
6} 11}
diff --git a/src/main/java/org/gnunet/voting/messages/BallotRegisterRespondMessage.java b/src/main/java/org/gnunet/voting/messages/BallotRegisterRespondMessage.java
index 15e10b8..f30f624 100644
--- a/src/main/java/org/gnunet/voting/messages/BallotRegisterRespondMessage.java
+++ b/src/main/java/org/gnunet/voting/messages/BallotRegisterRespondMessage.java
@@ -1,6 +1,12 @@
1package org.gnunet.voting.messages; 1package org.gnunet.voting.messages;
2 2
3import org.gnunet.construct.NestedMessage;
4import org.gnunet.construct.UnionCase;
5import org.gnunet.util.CryptoECC;
3import org.gnunet.util.GnunetMessage; 6import org.gnunet.util.GnunetMessage;
4 7
8@UnionCase(42002)
5public class BallotRegisterRespondMessage implements GnunetMessage.Body { 9public class BallotRegisterRespondMessage implements GnunetMessage.Body {
10 @NestedMessage
11 public CryptoECC.Signature registrationSignature;
6} 12}
diff --git a/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java b/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java
index d262047..e57b215 100644
--- a/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java
+++ b/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java
@@ -1,8 +1,12 @@
1package org.gnunet.voting.messages; 1package org.gnunet.voting.messages;
2 2
3import org.gnunet.construct.UnionCase;
4import org.gnunet.util.GnunetMessage;
5
3/** 6/**
4 * Request a certificate that allows a voter to submit a ballot. 7 * Request a certificate that allows a voter to submit a ballot.
5 * Sent by the voter to the certificate authority. 8 * Sent by the voter to the certificate authority.
6 */ 9 */
7public class CertificateRequestMessage { 10@UnionCase(42003)
11public class CertificateRequestMessage implements GnunetMessage.Body {
8} 12}
diff --git a/src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java b/src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java
index 87f688b..4a1bcd6 100644
--- a/src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java
+++ b/src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java
@@ -1,5 +1,9 @@
1package org.gnunet.voting.messages; 1package org.gnunet.voting.messages;
2 2
3 3
4public class CertificateResponseMessage { 4import org.gnunet.construct.UnionCase;
5import org.gnunet.util.GnunetMessage;
6
7@UnionCase(42004)
8public class CertificateResponseMessage implements GnunetMessage.Body {
5} 9}
diff --git a/src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java b/src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java
new file mode 100644
index 0000000..73f8fc8
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java
@@ -0,0 +1,28 @@
1/*
2 This file is part of GNUnet.
3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.voting.messages;
22
23import org.gnunet.construct.UnionCase;
24import org.gnunet.util.GnunetMessage;
25
26@UnionCase(42009)
27public class QueryFailureMessage implements GnunetMessage.Body {
28}
diff --git a/src/main/java/org/gnunet/voting/messages/QueryMessage.java b/src/main/java/org/gnunet/voting/messages/QueryMessage.java
new file mode 100644
index 0000000..abb04dc
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/messages/QueryMessage.java
@@ -0,0 +1,12 @@
1package org.gnunet.voting.messages;
2
3import org.gnunet.construct.NestedMessage;
4import org.gnunet.construct.UnionCase;
5import org.gnunet.util.GnunetMessage;
6import org.gnunet.util.HashCode;
7
8@UnionCase(42005)
9public class QueryMessage implements GnunetMessage.Body {
10 @NestedMessage
11 public HashCode ballotGUID;
12}
diff --git a/src/main/java/org/gnunet/voting/messages/QueryResponseMessage.java b/src/main/java/org/gnunet/voting/messages/QueryResponseMessage.java
new file mode 100644
index 0000000..4f0a8f6
--- /dev/null
+++ b/src/main/java/org/gnunet/voting/messages/QueryResponseMessage.java
@@ -0,0 +1,12 @@
1package org.gnunet.voting.messages;
2
3
4import org.gnunet.construct.*;
5import org.gnunet.util.GnunetMessage;
6import org.gnunet.util.HashCode;
7
8@UnionCase(42006)
9public class QueryResponseMessage implements GnunetMessage.Body {
10 @IntegerFill(signed = false, bitSize = 32)
11 public int[] results;
12}
diff --git a/src/main/java/org/gnunet/voting/messages/QueryResultMessage.java b/src/main/java/org/gnunet/voting/messages/QueryResultMessage.java
deleted file mode 100644
index 65f7ecc..0000000
--- a/src/main/java/org/gnunet/voting/messages/QueryResultMessage.java
+++ /dev/null
@@ -1,5 +0,0 @@
1package org.gnunet.voting.messages;
2
3public class QueryResultMessage {
4
5}
diff --git a/src/main/java/org/gnunet/voting/messages/QueryResultResponseMessage.java b/src/main/java/org/gnunet/voting/messages/QueryResultResponseMessage.java
deleted file mode 100644
index c36e722..0000000
--- a/src/main/java/org/gnunet/voting/messages/QueryResultResponseMessage.java
+++ /dev/null
@@ -1,5 +0,0 @@
1package org.gnunet.voting.messages;
2
3
4public class QueryResultResponseMessage {
5}
diff --git a/src/main/java/org/gnunet/voting/messages/SubmitMessage.java b/src/main/java/org/gnunet/voting/messages/SubmitMessage.java
index 6547a05..afd54b9 100644
--- a/src/main/java/org/gnunet/voting/messages/SubmitMessage.java
+++ b/src/main/java/org/gnunet/voting/messages/SubmitMessage.java
@@ -1,12 +1,19 @@
1package org.gnunet.voting.messages; 1package org.gnunet.voting.messages;
2 2
3import org.gnunet.construct.NestedMessage;
4import org.gnunet.construct.UInt32;
5import org.gnunet.construct.UnionCase;
3import org.gnunet.construct.ZeroTerminatedString; 6import org.gnunet.construct.ZeroTerminatedString;
4import org.gnunet.util.GnunetMessage; 7import org.gnunet.util.GnunetMessage;
8import org.gnunet.util.HashCode;
5 9
6/** 10/**
7 * Message send by the voter to the election authority to submit a vote. 11 * Message send by the voter to the election authority to submit a vote.
8 */ 12 */
13@UnionCase(42007)
9public class SubmitMessage implements GnunetMessage.Body { 14public class SubmitMessage implements GnunetMessage.Body {
10 @ZeroTerminatedString 15 @NestedMessage
11 public String ballot; 16 public HashCode ballotGuid;
17 @UInt32
18 public int choiceId;
12} 19}
diff --git a/src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java b/src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java
index 76dcac8..956ecf2 100644
--- a/src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java
+++ b/src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java
@@ -1,5 +1,9 @@
1package org.gnunet.voting.messages; 1package org.gnunet.voting.messages;
2 2
3 3
4public class SubmitResponseMessage { 4import org.gnunet.construct.UnionCase;
5import org.gnunet.util.GnunetMessage;
6
7@UnionCase(42008)
8public class SubmitResponseMessage implements GnunetMessage.Body {
5} 9}