diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-09-25 11:32:19 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-09-25 11:32:19 +0000 |
commit | aeeeaff2736808a6eaa2138272c46544676e49f3 (patch) | |
tree | 6278c672e4c4563664253683c92cd83cb1e0c636 /src/main/java/org/gnunet | |
parent | 67e978773774a0e7ef1f23209b884847837224ad (diff) | |
download | gnunet-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')
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 | |||
1 | package org.gnunet.consensus; | 21 | package org.gnunet.consensus; |
2 | 22 | ||
3 | public interface ConcludeCallback { | 23 | public 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 | |||
1 | package org.gnunet.consensus; | 21 | package 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 | |||
1 | package org.gnunet.consensus; | 21 | package org.gnunet.consensus; |
2 | 22 | ||
3 | import org.gnunet.construct.FillWith; | 23 | import 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 | |||
1 | package org.gnunet.consensus; | 21 | package org.gnunet.consensus; |
2 | 22 | ||
3 | import org.gnunet.mq.Envelope; | 23 | import 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 | |||
1 | package org.gnunet.consensus; | 21 | package 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 | |||
1 | package org.gnunet.consensus; | 21 | package org.gnunet.consensus; |
2 | 22 | ||
3 | public interface InsertDoneCallback { | 23 | public 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 | |||
1 | package org.gnunet.consensus; | 21 | package org.gnunet.consensus; |
2 | 22 | ||
3 | import org.gnunet.construct.FillWith; | 23 | import 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 | |||
1 | package org.gnunet.consensus; | 21 | package org.gnunet.consensus; |
2 | 22 | ||
3 | public interface NewElementCallback { | 23 | public 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 | |||
1 | package org.gnunet.consensus; | 21 | package org.gnunet.consensus; |
2 | 22 | ||
3 | import org.gnunet.construct.*; | 23 | import 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 | */ |
11 | public class MeshRunabout extends Runabout { | 11 | public 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 | */ |
8 | public interface TunnelEndHandler { | 8 | public 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; | |||
7 | import java.util.Map; | 7 | import java.util.Map; |
8 | 8 | ||
9 | 9 | ||
10 | /** | ||
11 | * Container for requests that are responded to with a matching request identification | ||
12 | */ | ||
10 | public class MatchingRequestContainer<K, T extends RequestContainer.Request> extends RequestContainer { | 13 | public 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 | */ | ||
1 | package org.gnunet.testbed; | 20 | package org.gnunet.testbed; |
2 | 21 | ||
3 | import com.google.common.base.Charsets; | 22 | import 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 | */ | ||
1 | package org.gnunet.testbed; | 20 | package org.gnunet.testbed; |
2 | 21 | ||
3 | import org.gnunet.mq.Envelope; | 22 | import org.gnunet.mq.Envelope; |
4 | import org.gnunet.requests.MatchingRequestContainer; | 23 | import org.gnunet.requests.MatchingRequestContainer; |
5 | import org.gnunet.requests.RequestContainer; | 24 | import org.gnunet.requests.RequestContainer; |
6 | import org.gnunet.requests.SequentialRequestContainer; | ||
7 | import org.gnunet.testbed.callbacks.*; | 25 | import org.gnunet.testbed.callbacks.*; |
8 | import org.gnunet.testbed.messages.ControllerInitMessage; | 26 | import org.gnunet.testbed.messages.*; |
9 | import org.gnunet.testbed.messages.PeerCreateMessage; | ||
10 | import org.gnunet.testbed.messages.PeerCreateSuccessMessage; | ||
11 | import org.gnunet.util.Cancelable; | 27 | import org.gnunet.util.Cancelable; |
12 | import org.gnunet.util.Client; | 28 | import org.gnunet.util.Client; |
13 | import org.gnunet.util.Configuration; | 29 | import 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 | */ |
27 | public class Controller { | 43 | public class Controller { |
28 | private 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 @@ | |||
1 | package 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 | */ | ||
10 | public 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 @@ | |||
1 | package org.gnunet.testbed.callbacks; | 1 | package 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 | */ | ||
10 | public interface OperationCompletionCallback { | 4 | public 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 | |||
21 | package org.gnunet.testbed.callbacks; | ||
22 | |||
23 | |||
24 | import org.gnunet.util.Configuration; | ||
25 | import org.gnunet.util.PeerIdentity; | ||
26 | |||
27 | public 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 | |||
21 | package org.gnunet.testbed.callbacks; | ||
22 | |||
23 | import org.gnunet.util.Configuration; | ||
24 | |||
25 | public 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 @@ | |||
1 | package 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 | */ |
10 | public class ConnectionEventMessage { | 20 | |
21 | package org.gnunet.testbed.messages; | ||
22 | |||
23 | |||
24 | import org.gnunet.construct.UInt32; | ||
25 | import org.gnunet.construct.UInt64; | ||
26 | import org.gnunet.construct.UnionCase; | ||
27 | import org.gnunet.util.GnunetMessage; | ||
28 | |||
29 | @UnionCase(472) | ||
30 | public 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 | */ | ||
1 | package org.gnunet.testbed.messages; | 20 | package org.gnunet.testbed.messages; |
2 | 21 | ||
3 | 22 | ||
@@ -8,7 +27,7 @@ import org.gnunet.construct.ZeroTerminatedString; | |||
8 | import org.gnunet.util.GnunetMessage; | 27 | import 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) |
14 | public class ControllerInitMessage implements GnunetMessage.Body { | 33 | public 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 @@ | |||
1 | package org.gnunet.testbed.messages; | ||
2 | |||
3 | |||
4 | public 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 @@ | |||
1 | package org.gnunet.testbed.messages; | 1 | package org.gnunet.testbed.messages; |
2 | 2 | ||
3 | import org.gnunet.construct.UInt32; | ||
4 | import org.gnunet.construct.UInt64; | ||
5 | import org.gnunet.construct.UnionCase; | ||
6 | import 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 | */ |
10 | public class GenericOperationSuccessMessage { | 13 | @UnionCase(475) |
14 | public 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 @@ | |||
1 | package org.gnunet.testbed.messages; | 1 | package org.gnunet.testbed.messages; |
2 | 2 | ||
3 | 3 | ||
4 | public class ManagePeerServiceMessage { | 4 | import org.gnunet.construct.*; |
5 | import org.gnunet.util.GnunetMessage; | ||
6 | |||
7 | @UnionCase(483) | ||
8 | public 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 @@ | |||
1 | package org.gnunet.testbed.messages; | 1 | package org.gnunet.testbed.messages; |
2 | 2 | ||
3 | /** | 3 | import org.gnunet.construct.UInt32; |
4 | * Created with IntelliJ IDEA. | 4 | import org.gnunet.construct.UInt64; |
5 | * User: dold | 5 | import org.gnunet.construct.UnionCase; |
6 | * Date: 9/10/13 | 6 | import org.gnunet.construct.ZeroTerminatedString; |
7 | * Time: 2:30 AM | 7 | import org.gnunet.util.GnunetMessage; |
8 | * To change this template use File | Settings | File Templates. | 8 | |
9 | */ | 9 | |
10 | public class OperationFailEventMessage { | 10 | @UnionCase(473) |
11 | public 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 @@ | |||
1 | package org.gnunet.testbed.messages; | ||
2 | |||
3 | /** | ||
4 | * Peer configuration and identity reply from controller to a client. | ||
5 | */ | ||
6 | public 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 | |||
21 | package org.gnunet.testbed.messages; | ||
22 | |||
23 | import org.gnunet.construct.UInt32; | ||
24 | import org.gnunet.construct.UInt64; | ||
25 | import org.gnunet.construct.UnionCase; | ||
26 | import org.gnunet.util.GnunetMessage; | ||
27 | |||
28 | @UnionCase(476) | ||
29 | public 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 | |||
21 | package org.gnunet.testbed.messages; | ||
22 | |||
23 | import org.gnunet.construct.*; | ||
24 | import org.gnunet.util.GnunetMessage; | ||
25 | import org.gnunet.util.PeerIdentity; | ||
26 | |||
27 | @UnionCase(477) | ||
28 | public 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 @@ | |||
1 | package org.gnunet.testbed.messages; | 1 | package org.gnunet.testbed.messages; |
2 | 2 | ||
3 | import org.gnunet.construct.*; | ||
4 | import 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 | */ |
7 | public class PeerReconfigureMessage { | 10 | @UnionCase(465) |
11 | public 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; | |||
24 | import org.gnunet.construct.Message; | 24 | import org.gnunet.construct.Message; |
25 | 25 | ||
26 | import java.io.File; | 26 | import java.io.File; |
27 | import java.io.FileOutputStream; | ||
27 | import java.io.IOError; | 28 | import java.io.IOError; |
28 | import java.io.IOException; | 29 | import java.io.IOException; |
29 | import java.math.BigInteger; | 30 | import java.math.BigInteger; |
30 | import java.nio.ByteBuffer; | 31 | import java.nio.ByteBuffer; |
31 | import java.nio.file.Files; | 32 | import java.nio.file.Files; |
33 | import java.nio.file.OpenOption; | ||
34 | import java.nio.file.StandardOpenOption; | ||
32 | import java.security.MessageDigest; | 35 | import java.security.MessageDigest; |
33 | import java.security.NoSuchAlgorithmException; | 36 | import java.security.NoSuchAlgorithmException; |
37 | import java.security.SecureRandom; | ||
38 | import 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 | ||
21 | package org.gnunet.util; | 21 | package org.gnunet.util; |
22 | 22 | ||
23 | import org.gnunet.construct.ProtocolViolationException; | ||
23 | import org.grothoff.Runabout; | 24 | import 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 | |||
21 | package org.gnunet.voting; | ||
22 | |||
23 | import com.google.common.base.Joiner; | ||
24 | import com.google.common.base.Optional; | ||
25 | import com.google.common.collect.BiMap; | ||
26 | import com.google.common.collect.HashBiMap; | ||
27 | import com.google.common.collect.Maps; | ||
28 | import org.gnunet.util.*; | ||
29 | |||
30 | import java.security.MessageDigest; | ||
31 | import java.security.NoSuchAlgorithmException; | ||
32 | import java.util.*; | ||
33 | import java.util.regex.Pattern; | ||
34 | |||
35 | /** | ||
36 | * Public information about an election. | ||
37 | */ | ||
38 | public 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; | |||
27 | import com.google.common.io.OutputSupplier; | 27 | import com.google.common.io.OutputSupplier; |
28 | import org.gnunet.mesh.Mesh; | 28 | import org.gnunet.mesh.Mesh; |
29 | import org.gnunet.mesh.MeshRunabout; | 29 | import org.gnunet.mesh.MeshRunabout; |
30 | import org.gnunet.mesh.TunnelEndHandler; | ||
30 | import org.gnunet.util.Configuration; | 31 | import org.gnunet.util.Configuration; |
31 | import org.gnunet.util.CryptoECC; | 32 | import org.gnunet.util.CryptoECC; |
33 | import org.gnunet.util.PeerIdentity; | ||
32 | import org.gnunet.util.Program; | 34 | import org.gnunet.util.Program; |
33 | import org.gnunet.util.getopt.Argument; | 35 | import org.gnunet.util.getopt.Argument; |
34 | import org.gnunet.util.getopt.ArgumentAction; | 36 | import org.gnunet.util.getopt.ArgumentAction; |
@@ -41,6 +43,7 @@ import java.io.FileOutputStream; | |||
41 | import java.io.IOException; | 43 | import java.io.IOException; |
42 | import java.io.InputStream; | 44 | import java.io.InputStream; |
43 | import java.nio.charset.Charset; | 45 | import java.nio.charset.Charset; |
46 | import java.util.List; | ||
44 | import java.util.regex.Pattern; | 47 | import 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 | |||
21 | package org.gnunet.voting; | ||
22 | |||
23 | /** | ||
24 | * Exception thrown when a ballot contains insufficient or invalid data. | ||
25 | */ | ||
26 | public 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 | |||
61 | package org.gnunet.voting; | ||
62 | |||
63 | |||
64 | import org.gnunet.mesh.Mesh; | ||
65 | import org.gnunet.mesh.MeshRunabout; | ||
66 | import org.gnunet.mesh.TunnelEndHandler; | ||
67 | import org.gnunet.util.Configuration; | ||
68 | import org.gnunet.util.PeerIdentity; | ||
69 | import org.gnunet.voting.messages.QueryFailureMessage; | ||
70 | import org.gnunet.voting.messages.QueryMessage; | ||
71 | import org.gnunet.voting.messages.QueryResponseMessage; | ||
72 | |||
73 | import java.io.File; | ||
74 | import java.util.List; | ||
75 | import java.util.Random; | ||
76 | |||
77 | public 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 | |||
41 | package org.gnunet.voting; | ||
42 | |||
43 | |||
44 | import org.gnunet.mesh.Mesh; | ||
45 | import org.gnunet.mesh.MeshRunabout; | ||
46 | import org.gnunet.mesh.TunnelEndHandler; | ||
47 | import org.gnunet.util.Configuration; | ||
48 | import org.gnunet.util.PeerIdentity; | ||
49 | import org.gnunet.voting.messages.QueryFailureMessage; | ||
50 | import org.gnunet.voting.messages.QueryMessage; | ||
51 | import org.gnunet.voting.messages.QueryResponseMessage; | ||
52 | |||
53 | import java.io.File; | ||
54 | import java.util.List; | ||
55 | import java.util.Random; | ||
56 | |||
57 | public 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 | |||
41 | package org.gnunet.voting; | ||
42 | |||
43 | |||
44 | import com.google.common.base.Charsets; | ||
45 | import com.google.common.io.Files; | ||
46 | import org.gnunet.mesh.Mesh; | ||
47 | import org.gnunet.mesh.MeshRunabout; | ||
48 | import org.gnunet.mesh.TunnelEndHandler; | ||
49 | import org.gnunet.testbed.CompressedConfig; | ||
50 | import org.gnunet.util.Configuration; | ||
51 | import org.gnunet.util.PeerIdentity; | ||
52 | import org.gnunet.voting.messages.BallotRegisterRequestMessage; | ||
53 | import org.gnunet.voting.messages.BallotRegisterRespondMessage; | ||
54 | import org.gnunet.voting.messages.SubmitMessage; | ||
55 | import org.gnunet.voting.messages.SubmitResponseMessage; | ||
56 | |||
57 | import java.io.File; | ||
58 | import java.io.IOException; | ||
59 | import java.util.List; | ||
60 | import java.util.Random; | ||
61 | |||
62 | public 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 | |||
21 | package org.gnunet.voting; | ||
22 | |||
23 | |||
24 | import org.gnunet.mesh.Mesh; | ||
25 | import org.gnunet.mesh.MeshRunabout; | ||
26 | import org.gnunet.mesh.TunnelEndHandler; | ||
27 | import org.gnunet.util.Configuration; | ||
28 | import org.gnunet.util.PeerIdentity; | ||
29 | import org.gnunet.voting.messages.SubmitMessage; | ||
30 | import org.gnunet.voting.messages.SubmitResponseMessage; | ||
31 | |||
32 | import java.io.File; | ||
33 | import java.util.List; | ||
34 | import java.util.Random; | ||
35 | |||
36 | public 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 | */ | ||
20 | package org.gnunet.voting; | ||
21 | |||
22 | |||
23 | import com.google.common.collect.Maps; | ||
24 | import org.gnunet.mesh.Mesh; | ||
25 | import org.gnunet.mesh.MeshRunabout; | ||
26 | import org.gnunet.testbed.CompressedConfig; | ||
27 | import org.gnunet.util.*; | ||
28 | import org.gnunet.voting.messages.*; | ||
29 | import org.slf4j.Logger; | ||
30 | import org.slf4j.LoggerFactory; | ||
31 | |||
32 | import java.util.*; | ||
33 | |||
34 | public 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 | */ | ||
20 | package org.gnunet.voting; | ||
21 | |||
22 | |||
23 | import com.google.common.collect.Maps; | ||
24 | import org.gnunet.mesh.Mesh; | ||
25 | import org.gnunet.mesh.MeshRunabout; | ||
26 | import org.gnunet.util.CryptoECC; | ||
27 | import org.gnunet.util.RelativeTime; | ||
28 | import org.gnunet.util.Service; | ||
29 | import org.gnunet.voting.messages.BallotRegisterRequestMessage; | ||
30 | import org.gnunet.voting.messages.CertificateRequestMessage; | ||
31 | import org.gnunet.voting.messages.QueryResultMessage; | ||
32 | import org.gnunet.voting.messages.SubmitMessage; | ||
33 | |||
34 | import java.util.HashSet; | ||
35 | import java.util.Map; | ||
36 | import java.util.Set; | ||
37 | |||
38 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | 1 | package org.gnunet.voting.messages; |
2 | 2 | ||
3 | import org.gnunet.construct.IntegerFill; | ||
4 | import org.gnunet.construct.UnionCase; | ||
3 | import org.gnunet.util.GnunetMessage; | 5 | import org.gnunet.util.GnunetMessage; |
4 | 6 | ||
7 | @UnionCase(42001) | ||
5 | public class BallotRegisterRequestMessage implements GnunetMessage.Body { | 8 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | 1 | package org.gnunet.voting.messages; |
2 | 2 | ||
3 | import org.gnunet.construct.NestedMessage; | ||
4 | import org.gnunet.construct.UnionCase; | ||
5 | import org.gnunet.util.CryptoECC; | ||
3 | import org.gnunet.util.GnunetMessage; | 6 | import org.gnunet.util.GnunetMessage; |
4 | 7 | ||
8 | @UnionCase(42002) | ||
5 | public class BallotRegisterRespondMessage implements GnunetMessage.Body { | 9 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | 1 | package org.gnunet.voting.messages; |
2 | 2 | ||
3 | import org.gnunet.construct.UnionCase; | ||
4 | import 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 | */ |
7 | public class CertificateRequestMessage { | 10 | @UnionCase(42003) |
11 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | 1 | package org.gnunet.voting.messages; |
2 | 2 | ||
3 | 3 | ||
4 | public class CertificateResponseMessage { | 4 | import org.gnunet.construct.UnionCase; |
5 | import org.gnunet.util.GnunetMessage; | ||
6 | |||
7 | @UnionCase(42004) | ||
8 | public 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 | |||
21 | package org.gnunet.voting.messages; | ||
22 | |||
23 | import org.gnunet.construct.UnionCase; | ||
24 | import org.gnunet.util.GnunetMessage; | ||
25 | |||
26 | @UnionCase(42009) | ||
27 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | import org.gnunet.construct.NestedMessage; | ||
4 | import org.gnunet.construct.UnionCase; | ||
5 | import org.gnunet.util.GnunetMessage; | ||
6 | import org.gnunet.util.HashCode; | ||
7 | |||
8 | @UnionCase(42005) | ||
9 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | |||
4 | import org.gnunet.construct.*; | ||
5 | import org.gnunet.util.GnunetMessage; | ||
6 | import org.gnunet.util.HashCode; | ||
7 | |||
8 | @UnionCase(42006) | ||
9 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | |||
4 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | 1 | package org.gnunet.voting.messages; |
2 | 2 | ||
3 | import org.gnunet.construct.NestedMessage; | ||
4 | import org.gnunet.construct.UInt32; | ||
5 | import org.gnunet.construct.UnionCase; | ||
3 | import org.gnunet.construct.ZeroTerminatedString; | 6 | import org.gnunet.construct.ZeroTerminatedString; |
4 | import org.gnunet.util.GnunetMessage; | 7 | import org.gnunet.util.GnunetMessage; |
8 | import 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) | ||
9 | public class SubmitMessage implements GnunetMessage.Body { | 14 | public 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 @@ | |||
1 | package org.gnunet.voting.messages; | 1 | package org.gnunet.voting.messages; |
2 | 2 | ||
3 | 3 | ||
4 | public class SubmitResponseMessage { | 4 | import org.gnunet.construct.UnionCase; |
5 | import org.gnunet.util.GnunetMessage; | ||
6 | |||
7 | @UnionCase(42008) | ||
8 | public class SubmitResponseMessage implements GnunetMessage.Body { | ||
5 | } | 9 | } |