diff options
65 files changed, 2924 insertions, 748 deletions
@@ -1,91 +1,46 @@ | |||
1 | == testbed == | 1 | testbed api is now quite complete |
2 | 2 | * problem with reconfigure was a bug in the testbed service | |
3 | padding: PACKED / NETWORK_STRUCT don't really pack some misaligned structs: | 3 | * only thing left to to is to implement arm for manageService |
4 | struct GNUNET_TESTBED_PeerConfigurationInformationMessage | 4 | * (BUT: I don't get how arm works in conjunction with testbed -- when the arm api can't connect to |
5 | is misaligned anyway, *but* sizeof the struct is 84, when it should be 82! | 5 | arm it tries to start the arm service *locally*, which is often wrong ...) |
6 | 6 | * talked to sriharsha about it | |
7 | see https://gnunet.org/bugs/view.php?id=3043 | 7 | |
8 | 8 | gnunet-java finally has a proper stream tokenizer ... | |
9 | I managed to break testbed (this is a GNUNET_assert, no GNUNET_break) | 9 | * and locking has been removes from Scheduler, Helper is properly implemented |
10 | Sep 24 20:06:14-146897 testbed-18586 ERROR Assertion failed at testing.c:1548. | 10 | |
11 | but this only occurs *after* the shutdown and when trying to reconfigure a peer! | 11 | new java API implementation for identity :) |
12 | 12 | * why is there no way to import keys? | |
13 | OPTIONS/PREFIX does not work with testbed helper | 13 | * at least API-wise |
14 | 14 | * voting should use identity ... | |
15 | what works (and is tested) now in org.gnunet.testbed: | 15 | |
16 | * creating and destroying peers | 16 | timing information in ballot: we talked about round times, |
17 | * starting and stopping peers | 17 | but shouldn't this be done transparently by consensus? |
18 | * getting peer id / configuration | 18 | aren't START_TIME, CLOSING_TIME, QUERY_TIME, END_TIME and maybe CONSENSUS_PARAMS be enough? |
19 | * overlay-connecting two peers | 19 | |
20 | other stuff: | 20 | certificate authority: is the CAs pubkey different from its peer? |
21 | * does gnunet-java need barriers? | 21 | * it definitely makes sense to have it seperate for other cert methods |
22 | * what's the state of the overlay implementation | 22 | * like sending a cert per email, snail mail, social network ... |
23 | * does service_connect do anything other than retrieve the configuration? | 23 | * how do we specify how to reach the cert? one peer? multiple peers? |
24 | * primary purpose is to be able to have opqueue management, right? | 24 | * maybe use GADS? (I know very little about GADS right now) |
25 | * why do we have manage service when we have arm? | 25 | * does it even make sense to have the CA service at this time? |
26 | * someone has to start arm, I suppose? | ||
27 | |||
28 | == crypto == | ||
29 | two types of public keys, do I understand the reasons correctly: | ||
30 | * NaCl compatibility | ||
31 | * fastest representation for each type of operation | ||
32 | |||
33 | why is there no way to convert from signing key -> encryption key? | ||
34 | * other way around is not possible | ||
35 | |||
36 | |||
37 | == voting == | ||
38 | 26 | ||
39 | what now works: | 27 | what now works: |
40 | * creating a ballot and registering it | 28 | * authorities check for double vote submission, late / early voting, early result query, |
41 | * selecting a choice in the ballot and submitting it | 29 | double registering, vouchers (I don't like to call vouchers receipts because that term has |
42 | * vote + 512-bit ballot GUID | 30 | a certain meaning in voting literature already) |
43 | * querying the results (also with the GUID) | ||
44 | |||
45 | next steps?? | ||
46 | - Ballot: (a) voter ID, (b) election information, (c) election eligibility group (Bavaria 18+), (d) ballot GUID | ||
47 | - no double submission: check: no duplicate voter ID (for any given election) | ||
48 | - no early queries | ||
49 | - voter <--> CA interaction | ||
50 | => ideally, CA has a list of voter public keys or at least a policy (i.e. "accept all") | ||
51 | for a certain voter group (i.e. Bavaria 18+). | ||
52 | => CA also has a private CA key (surprise!) | ||
53 | => Voter has voter public key and voter group, sends THOSE to CA; | ||
54 | => CA signs: this voter is in this voter group (with expiration time for signature!) | ||
55 | => voter takes signature, can re-use it for ALL elections with this voter group | ||
56 | - Authorities have CA public keys, check voter group sigs. | ||
57 | |||
58 | what should be stored in the ballot about authorities: peer identities or peer public keys? | ||
59 | => public keys | ||
60 | |||
61 | * pubkey makes more sense, but I have the feeling that GNUnet prefers to use | ||
62 | peer IDs whenever possible | ||
63 | => Nah. | ||
64 | |||
65 | docs of identity service say: | ||
66 | For giving names to other users and manage their public keys securely, we use GNS. | ||
67 | In what way does GNS manage public keys? | ||
68 | GNS allows you to give names to other user's public keys. | ||
69 | Does GNS in any way relate peer identities to public keys? | ||
70 | No. | ||
71 | |||
72 | persistent storage of tallies? | ||
73 | => Later. | ||
74 | 31 | ||
75 | now that the pubkey is smaller, are there reasons for still having | 32 | but: group certs are not checked right now |
76 | a separate peer identity? | ||
77 | * except for that it would be a lot of work to change now | ||
78 | => exactly. | ||
79 | 33 | ||
80 | the command line took looks a bit complicated now, any suggestions? | 34 | how to test voting without waiting too long or missing the right time? |
81 | => Later. | ||
82 | 35 | ||
83 | asking permission to vote should not require the private key, right? | 36 | any progress on crypto? |
84 | * how do we do this interface-wise? pubkey on the command line? | 37 | * luckily the private key has the same size, so identity can be used |
85 | => Identity service, ego! | ||
86 | 38 | ||
87 | == general java stuff == | 39 | next: |
88 | what's your opinion on option types: should they be used more in gnunet-java? | 40 | * use identity |
41 | * multiple authorities should do consensus on unencrypted votes | ||
42 | * tests for this with testbed | ||
43 | * encrypting votes | ||
89 | 44 | ||
90 | We have a lot of callbacks in java that all do almost the same. Should we have a generic callback type? | 45 | suggestions? |
91 | 46 | ||
diff --git a/bin/gnunet-ballot b/bin/gnunet-ballot new file mode 100755 index 0000000..e76c423 --- /dev/null +++ b/bin/gnunet-ballot | |||
@@ -0,0 +1,12 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | if [ "%GNJ_INSTALLED" = "true" ]; | ||
4 | then | ||
5 | export CLASSPATH="%INSTALL_PATH/share/java/*" | ||
6 | else | ||
7 | DIR=`dirname $0` | ||
8 | # if we are in the development environment use class files directly instead of jar | ||
9 | export CLASSPATH="$DIR/../build-gradle/classes/main/:$DIR/../build-gradle/resources/main/:$DIR/../lib/*" | ||
10 | fi | ||
11 | |||
12 | java -ea org.gnunet.voting.BallotTool "$@" | ||
diff --git a/bin/gnunet-daemon-ballot-ca b/bin/gnunet-daemon-ballot-ca new file mode 100755 index 0000000..b85a67f --- /dev/null +++ b/bin/gnunet-daemon-ballot-ca | |||
@@ -0,0 +1,12 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | if [ "%GNJ_INSTALLED" = "true" ]; | ||
4 | then | ||
5 | export CLASSPATH="%INSTALL_PATH/share/java/*" | ||
6 | else | ||
7 | DIR=`dirname $0` | ||
8 | # if we are in the development environment use class files directly instead of jar | ||
9 | export CLASSPATH="$DIR/../build-gradle/classes/main/:$DIR/../build-gradle/resources/main/:$DIR/../lib/*" | ||
10 | fi | ||
11 | |||
12 | java -ea org.gnunet.voting.CertificateAuthorityDaemon "$@" | ||
diff --git a/bin/gnunet-daemon-ballot-tally b/bin/gnunet-daemon-ballot-tally new file mode 100755 index 0000000..b24b5eb --- /dev/null +++ b/bin/gnunet-daemon-ballot-tally | |||
@@ -0,0 +1,12 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | if [ "%GNJ_INSTALLED" = "true" ]; | ||
4 | then | ||
5 | export CLASSPATH="%INSTALL_PATH/share/java/*" | ||
6 | else | ||
7 | DIR=`dirname $0` | ||
8 | # if we are in the development environment use class files directly instead of jar | ||
9 | export CLASSPATH="$DIR/../build-gradle/classes/main/:$DIR/../build-gradle/resources/main/:$DIR/../lib/*" | ||
10 | fi | ||
11 | |||
12 | java -ea org.gnunet.voting.TallyAuthorityDaemon "$@" | ||
diff --git a/src/main/java/org/gnunet/arm/Arm.java b/src/main/java/org/gnunet/arm/Arm.java new file mode 100644 index 0000000..503413f --- /dev/null +++ b/src/main/java/org/gnunet/arm/Arm.java | |||
@@ -0,0 +1,70 @@ | |||
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.arm; | ||
22 | |||
23 | import org.gnunet.util.Client; | ||
24 | import org.gnunet.util.Configuration; | ||
25 | |||
26 | /** | ||
27 | * API for the Automatic Restart Manager (ARM) | ||
28 | */ | ||
29 | public class Arm { | ||
30 | private final Configuration configuration; | ||
31 | private Client client; | ||
32 | public Arm(Configuration configuration) { | ||
33 | this.configuration = configuration; | ||
34 | client = new Client("arm", configuration); | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * Disconnect from ARM, the Arm object may not be used afterwards. | ||
39 | */ | ||
40 | public void disconnect() { | ||
41 | client.disconnect(); | ||
42 | } | ||
43 | public void requestServiceList(ServiceListHandler serviceListHandler) { | ||
44 | |||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Request a service to be stopped. | ||
49 | * Stopping arm itself will not invalidate its handle, and | ||
50 | * ARM API will try to restore connection to the ARM service, | ||
51 | * even if ARM connection was lost because you asked for ARM to be stopped. | ||
52 | * Call Arm.disconnect to free the handle and prevent | ||
53 | * further connection attempts. | ||
54 | * | ||
55 | * @param serviceName name of the service | ||
56 | * @param resultHandler called with the result of the request | ||
57 | */ | ||
58 | public void requestServiceStop(String serviceName, ResultHandler resultHandler) { | ||
59 | |||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Request for a service to be started. | ||
64 | * | ||
65 | * @param serviceName name of the service | ||
66 | */ | ||
67 | public void requestServiceStart(String serviceName, ResultHandler resultHandler) { | ||
68 | |||
69 | } | ||
70 | } | ||
diff --git a/src/main/java/org/gnunet/arm/ArmMonitor.java b/src/main/java/org/gnunet/arm/ArmMonitor.java new file mode 100644 index 0000000..641b862 --- /dev/null +++ b/src/main/java/org/gnunet/arm/ArmMonitor.java | |||
@@ -0,0 +1,27 @@ | |||
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.arm; | ||
22 | |||
23 | /** | ||
24 | * API for monitoring ARM services. | ||
25 | */ | ||
26 | public class ArmMonitor { | ||
27 | } | ||
diff --git a/src/main/java/org/gnunet/arm/ResultHandler.java b/src/main/java/org/gnunet/arm/ResultHandler.java new file mode 100644 index 0000000..05c34f9 --- /dev/null +++ b/src/main/java/org/gnunet/arm/ResultHandler.java | |||
@@ -0,0 +1,31 @@ | |||
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.arm; | ||
22 | |||
23 | /** | ||
24 | * Created with IntelliJ IDEA. | ||
25 | * User: dold | ||
26 | * Date: 10/7/13 | ||
27 | * Time: 4:00 PM | ||
28 | * To change this template use File | Settings | File Templates. | ||
29 | */ | ||
30 | public interface ResultHandler { | ||
31 | } | ||
diff --git a/src/main/java/org/gnunet/arm/ServiceListHandler.java b/src/main/java/org/gnunet/arm/ServiceListHandler.java new file mode 100644 index 0000000..8d9de04 --- /dev/null +++ b/src/main/java/org/gnunet/arm/ServiceListHandler.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.arm; | ||
22 | |||
23 | |||
24 | import java.util.List; | ||
25 | |||
26 | public interface ServiceListHandler { | ||
27 | void onServiceList(List<String> services); | ||
28 | } | ||
diff --git a/src/main/java/org/gnunet/arm/ServiceStatusHandler.java b/src/main/java/org/gnunet/arm/ServiceStatusHandler.java new file mode 100644 index 0000000..cedcc48 --- /dev/null +++ b/src/main/java/org/gnunet/arm/ServiceStatusHandler.java | |||
@@ -0,0 +1,25 @@ | |||
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.arm; | ||
22 | |||
23 | public interface ServiceStatusHandler { | ||
24 | |||
25 | } | ||
diff --git a/src/main/java/org/gnunet/arm/messages/ListResultMessage.java b/src/main/java/org/gnunet/arm/messages/ListResultMessage.java new file mode 100644 index 0000000..03f995f --- /dev/null +++ b/src/main/java/org/gnunet/arm/messages/ListResultMessage.java | |||
@@ -0,0 +1,41 @@ | |||
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.arm.messages; | ||
22 | |||
23 | import org.gnunet.construct.*; | ||
24 | import org.gnunet.util.GnunetMessage; | ||
25 | |||
26 | @UnionCase(13) | ||
27 | public class ListResultMessage implements GnunetMessage.Body { | ||
28 | public class StringMessage implements Message { | ||
29 | @ZeroTerminatedString | ||
30 | public String string; | ||
31 | } | ||
32 | |||
33 | @UInt64 | ||
34 | public long requestId; | ||
35 | |||
36 | @UInt16 | ||
37 | public int count; | ||
38 | |||
39 | @FillWith | ||
40 | public StringMessage[] services; | ||
41 | } | ||
diff --git a/src/main/java/org/gnunet/arm/messages/RequestMessage.java b/src/main/java/org/gnunet/arm/messages/RequestMessage.java new file mode 100644 index 0000000..fa0c18c --- /dev/null +++ b/src/main/java/org/gnunet/arm/messages/RequestMessage.java | |||
@@ -0,0 +1,25 @@ | |||
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.arm.messages; | ||
22 | |||
23 | |||
24 | public class RequestMessage { | ||
25 | } | ||
diff --git a/src/main/java/org/gnunet/arm/messages/ResultMessage.java b/src/main/java/org/gnunet/arm/messages/ResultMessage.java new file mode 100644 index 0000000..4883c14 --- /dev/null +++ b/src/main/java/org/gnunet/arm/messages/ResultMessage.java | |||
@@ -0,0 +1,35 @@ | |||
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.arm.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(10) | ||
29 | public class ResultMessage implements GnunetMessage.Body { | ||
30 | @UInt64 | ||
31 | public long requestId; | ||
32 | |||
33 | @UInt32 | ||
34 | public int result; | ||
35 | } | ||
diff --git a/src/main/java/org/gnunet/arm/messages/StatusMessage.java b/src/main/java/org/gnunet/arm/messages/StatusMessage.java new file mode 100644 index 0000000..cdfde6c --- /dev/null +++ b/src/main/java/org/gnunet/arm/messages/StatusMessage.java | |||
@@ -0,0 +1,61 @@ | |||
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.arm.messages; | ||
42 | |||
43 | import org.gnunet.construct.*; | ||
44 | import org.gnunet.util.GnunetMessage; | ||
45 | |||
46 | @UnionCase(11) | ||
47 | public class StatusMessage implements GnunetMessage.Body { | ||
48 | public class StringMessage implements Message { | ||
49 | @ZeroTerminatedString | ||
50 | public String string; | ||
51 | } | ||
52 | |||
53 | @UInt64 | ||
54 | public long requestId; | ||
55 | |||
56 | @UInt32 | ||
57 | public int status; | ||
58 | |||
59 | @ZeroTerminatedString | ||
60 | public String serviceName; | ||
61 | } | ||
diff --git a/src/main/java/org/gnunet/construct/parsers/FillParser.java b/src/main/java/org/gnunet/construct/parsers/FillParser.java index 156e120..19ce252 100644 --- a/src/main/java/org/gnunet/construct/parsers/FillParser.java +++ b/src/main/java/org/gnunet/construct/parsers/FillParser.java | |||
@@ -66,15 +66,12 @@ public class FillParser implements Parser { | |||
66 | throw new AssertionError("FillParser expects a non-null frameSizePath. Does the message have a @FrameSizePath annotation?"); | 66 | throw new AssertionError("FillParser expects a non-null frameSizePath. Does the message have a @FrameSizePath annotation?"); |
67 | } | 67 | } |
68 | 68 | ||
69 | |||
70 | |||
71 | final int frameSize = ReflectUtil.justGetInt(dstObj, frameSizePath); | 69 | final int frameSize = ReflectUtil.justGetInt(dstObj, frameSizePath); |
72 | int remaining = frameOffset + frameSize - srcBuf.position(); | 70 | int remaining = frameOffset + frameSize - srcBuf.position(); |
73 | int size = 0; | 71 | int size = 0; |
74 | 72 | ||
75 | Class<?> elemType = targetField.getType().getComponentType(); | 73 | Class<?> elemType = targetField.getType().getComponentType(); |
76 | 74 | ||
77 | |||
78 | ArrayList<Message> list = new ArrayList<Message>(10); | 75 | ArrayList<Message> list = new ArrayList<Message>(10); |
79 | 76 | ||
80 | while (remaining > 0) { | 77 | while (remaining > 0) { |
diff --git a/src/main/java/org/gnunet/construct/parsers/StringParser.java b/src/main/java/org/gnunet/construct/parsers/StringParser.java index b4e62ca..a91778b 100644 --- a/src/main/java/org/gnunet/construct/parsers/StringParser.java +++ b/src/main/java/org/gnunet/construct/parsers/StringParser.java | |||
@@ -67,7 +67,7 @@ public class StringParser implements Parser { | |||
67 | if (frameSizePath == null) { | 67 | if (frameSizePath == null) { |
68 | throw new AssertionError("optional string with no length field in the message!"); | 68 | throw new AssertionError("optional string with no length field in the message!"); |
69 | } | 69 | } |
70 | final int frameSize = ReflectUtil.justGetInt(dstObj, frameSizePath); | 70 | final int frameSize = ReflectUtil.justGetInt(frameObj, frameSizePath); |
71 | int remaining = frameOffset + frameSize - srcBuf.position(); | 71 | int remaining = frameOffset + frameSize - srcBuf.position(); |
72 | 72 | ||
73 | if (remaining == 0) { | 73 | if (remaining == 0) { |
@@ -79,6 +79,11 @@ public class StringParser implements Parser { | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | if (!srcBuf.hasRemaining()) { | ||
83 | throw new ProtocolViolationException("no data for non-optional string field " + | ||
84 | targetField); | ||
85 | } | ||
86 | |||
82 | int length = 0; | 87 | int length = 0; |
83 | 88 | ||
84 | while (srcBuf.get(srcBuf.position() + length) != 0) { | 89 | while (srcBuf.get(srcBuf.position() + length) != 0) { |
diff --git a/src/main/java/org/gnunet/identity/Identity.java b/src/main/java/org/gnunet/identity/Identity.java new file mode 100644 index 0000000..657a0b9 --- /dev/null +++ b/src/main/java/org/gnunet/identity/Identity.java | |||
@@ -0,0 +1,344 @@ | |||
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.identity; | ||
22 | |||
23 | |||
24 | import com.google.common.collect.Lists; | ||
25 | import org.gnunet.identity.messages.*; | ||
26 | import org.gnunet.mq.Envelope; | ||
27 | import org.gnunet.requests.RequestContainer; | ||
28 | import org.gnunet.requests.SequentialRequestContainer; | ||
29 | import org.gnunet.util.*; | ||
30 | import org.slf4j.Logger; | ||
31 | import org.slf4j.LoggerFactory; | ||
32 | |||
33 | import java.util.List; | ||
34 | |||
35 | public class Identity { | ||
36 | private static final Logger logger = LoggerFactory | ||
37 | .getLogger(Identity.class); | ||
38 | private Configuration configuration; | ||
39 | private SequentialRequestContainer<IdentityRequest> requests; | ||
40 | private Client client; | ||
41 | private IdentityListCallback identityListCallback; | ||
42 | private List<Ego> knownEgos = Lists.newLinkedList(); | ||
43 | |||
44 | private static Ego anonymousEgo; | ||
45 | |||
46 | public static class Ego { | ||
47 | private String name; | ||
48 | private CryptoECC.PrivateKey privateKey; | ||
49 | |||
50 | public Ego(String egoName, CryptoECC.PrivateKey privateKey) { | ||
51 | this.name = egoName; | ||
52 | this.privateKey = privateKey; | ||
53 | } | ||
54 | public CryptoECC.PrivateKey getPrivateKey() { | ||
55 | return privateKey; | ||
56 | } | ||
57 | public CryptoECC.PublicSignKey getPublicKey() { | ||
58 | return CryptoECC.computePublicKey(privateKey); | ||
59 | } | ||
60 | public String getName() { | ||
61 | return name; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | public abstract class IdentityRequest extends RequestContainer.Request { | ||
66 | |||
67 | public void onError(String errorMessage) { | ||
68 | throw new AssertionError("unexpected error message: " + errorMessage); | ||
69 | } | ||
70 | |||
71 | public void onResult() { | ||
72 | throw new AssertionError("unexpected result"); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | public class GetDefaultRequest extends IdentityRequest { | ||
77 | IdentityCallback identityCallback; | ||
78 | String serviceName; | ||
79 | GetDefaultRequest(String serviceName, IdentityCallback identityCallback) { | ||
80 | this.identityCallback = identityCallback; | ||
81 | this.serviceName = serviceName; | ||
82 | } | ||
83 | @Override | ||
84 | public Envelope assembleRequest() { | ||
85 | GetDefaultMessage m = new GetDefaultMessage(); | ||
86 | m.nameLength = serviceName.length() + 1; | ||
87 | m.serviceName = serviceName; | ||
88 | return new Envelope(m); | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public void onError(String errorMessage) { | ||
93 | identityCallback.onError(errorMessage); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | public class SetDefaultRequest extends IdentityRequest { | ||
98 | IdentityContinuation cont; | ||
99 | String serviceName; | ||
100 | Ego ego; | ||
101 | SetDefaultRequest(String serviceName, Ego ego) { | ||
102 | this.serviceName = serviceName; | ||
103 | this.ego = ego; | ||
104 | } | ||
105 | @Override | ||
106 | public Envelope assembleRequest() { | ||
107 | SetDefaultMessage m = new SetDefaultMessage(); | ||
108 | m.nameLength = serviceName.length() + 1; | ||
109 | m.serviceName = serviceName; | ||
110 | m.privateKey = ego.privateKey; | ||
111 | return new Envelope(m); | ||
112 | } | ||
113 | @Override | ||
114 | public void onError(String errorMessage) { | ||
115 | cont.onError(errorMessage); | ||
116 | } | ||
117 | @Override | ||
118 | public void onResult() { | ||
119 | cont.onDone(); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | public class RenameRequest extends IdentityRequest { | ||
124 | IdentityContinuation cont; | ||
125 | String oldName; | ||
126 | String newName; | ||
127 | RenameRequest(String newName, String oldName) { | ||
128 | this.oldName = oldName; | ||
129 | this.newName = newName; | ||
130 | } | ||
131 | @Override | ||
132 | public Envelope assembleRequest() { | ||
133 | RenameMessage m = new RenameMessage(); | ||
134 | m.newName = newName; | ||
135 | m.newNameLength = newName.length() + 1; | ||
136 | m.oldName = oldName; | ||
137 | m.oldNameLength = oldName.length() + 1; | ||
138 | return new Envelope(m); | ||
139 | } | ||
140 | @Override | ||
141 | public void onError(String errorMessage) { | ||
142 | cont.onError(errorMessage); | ||
143 | } | ||
144 | @Override | ||
145 | public void onResult() { | ||
146 | cont.onDone(); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | public class DeleteRequest extends IdentityRequest { | ||
151 | IdentityContinuation cont; | ||
152 | String name; | ||
153 | DeleteRequest(String name) { | ||
154 | this.name = name; | ||
155 | } | ||
156 | @Override | ||
157 | public Envelope assembleRequest() { | ||
158 | DeleteMessage m = new DeleteMessage(); | ||
159 | m.name = name; | ||
160 | m.nameLength = name.length() + 1; | ||
161 | return new Envelope(m); | ||
162 | } | ||
163 | @Override | ||
164 | public void onError(String errorMessage) { | ||
165 | cont.onError(errorMessage); | ||
166 | } | ||
167 | @Override | ||
168 | public void onResult() { | ||
169 | cont.onDone(); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | public class CreateRequest extends IdentityRequest { | ||
174 | final CryptoECC.PrivateKey privateKey; | ||
175 | IdentityContinuation cont; | ||
176 | String name; | ||
177 | CreateRequest(String name, CryptoECC.PrivateKey privateKey, IdentityContinuation cont) { | ||
178 | this.cont = cont; | ||
179 | this.privateKey = privateKey; | ||
180 | this.name = name; | ||
181 | } | ||
182 | @Override | ||
183 | public Envelope assembleRequest() { | ||
184 | CreateRequestMessage m = new CreateRequestMessage(); | ||
185 | m.name = name; | ||
186 | m.nameLength = name.length() + 1; | ||
187 | m.privateKey = privateKey; | ||
188 | return new Envelope(m); | ||
189 | } | ||
190 | @Override | ||
191 | public void onError(String errorMessage) { | ||
192 | cont.onError(errorMessage); | ||
193 | } | ||
194 | |||
195 | @Override | ||
196 | public void onResult() { | ||
197 | cont.onDone(); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | public static Ego getAnonymousEgo() { | ||
202 | if (anonymousEgo == null) { | ||
203 | anonymousEgo = new Ego(null, CryptoECC.getAnonymous()); | ||
204 | } | ||
205 | return anonymousEgo; | ||
206 | } | ||
207 | |||
208 | |||
209 | public Identity() { | ||
210 | // do nothing | ||
211 | } | ||
212 | |||
213 | public void connect(Configuration configuration, IdentityListCallback identityListCallback) { | ||
214 | this.configuration = configuration; | ||
215 | this.client = new Client("identity", configuration); | ||
216 | this.client.installReceiver(new IdentityReceiver()); | ||
217 | requests = new SequentialRequestContainer<IdentityRequest>(this.client); | ||
218 | this.identityListCallback = identityListCallback; | ||
219 | StartMessage m = new StartMessage(); | ||
220 | client.send(m); | ||
221 | } | ||
222 | |||
223 | public Cancelable get(String serviceName, IdentityCallback identityCallback) { | ||
224 | return requests.addRequest(new GetDefaultRequest(serviceName, identityCallback)); | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * Set the default ego for a service. | ||
229 | * | ||
230 | * @param serviceName service | ||
231 | * @param ego ego | ||
232 | * @return object for cancellation | ||
233 | */ | ||
234 | public Cancelable set(String serviceName, Ego ego) { | ||
235 | return requests.addRequest(new SetDefaultRequest(serviceName, ego)); | ||
236 | } | ||
237 | |||
238 | public void disconnect() { | ||
239 | client.disconnect(); | ||
240 | client = null; | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * Create a new ego with the given name. | ||
245 | * | ||
246 | * @param name ego name | ||
247 | * @param cont continuation | ||
248 | * @return object for cancellation | ||
249 | */ | ||
250 | public Cancelable create(String name, IdentityContinuation cont) { | ||
251 | CryptoECC.PrivateKey privateKey = CryptoECC.PrivateKey.createRandom(); | ||
252 | return requests.addRequest(new CreateRequest(name, privateKey, cont)); | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * Rename an ego. | ||
257 | * | ||
258 | * @param oldName old name of the ego | ||
259 | * @param newName new name of the ego | ||
260 | * @return object for cancellation | ||
261 | */ | ||
262 | public Cancelable rename(String oldName, String newName) { | ||
263 | return requests.addRequest(new RenameRequest(newName, oldName)); | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * Delete an ego. | ||
268 | * | ||
269 | * @param name name of the ego to delete | ||
270 | * @return object for cancellation | ||
271 | */ | ||
272 | public Cancelable delete(String name) { | ||
273 | return requests.addRequest(new DeleteRequest(name)); | ||
274 | } | ||
275 | |||
276 | private Ego getEgoForKey(CryptoECC.PrivateKey privateKey) { | ||
277 | for (Ego ex : knownEgos) { | ||
278 | if (ex.privateKey.equals(privateKey)) { | ||
279 | return ex; | ||
280 | } | ||
281 | } | ||
282 | return null; | ||
283 | } | ||
284 | |||
285 | public class IdentityReceiver extends RunaboutMessageReceiver { | ||
286 | @Override | ||
287 | public void handleError() { | ||
288 | logger.warn("identity service disconnected"); | ||
289 | client.reconnect(); | ||
290 | } | ||
291 | |||
292 | public void visit(ResultCodeMessage m) { | ||
293 | IdentityRequest r = requests.getRequest(); | ||
294 | if (null == r) { | ||
295 | logger.warn("unsolicited result code message"); | ||
296 | return; | ||
297 | } | ||
298 | if (m.errorMessage != null) { | ||
299 | r.onError(m.errorMessage); | ||
300 | } else { | ||
301 | r.onResult(); | ||
302 | } | ||
303 | requests.next(); | ||
304 | } | ||
305 | |||
306 | public void visit(SetDefaultMessage m) { | ||
307 | IdentityRequest r = requests.getRequest(); | ||
308 | if (!(r instanceof GetDefaultRequest)) { | ||
309 | logger.error("unexpected 'default ego' response"); | ||
310 | return; | ||
311 | } | ||
312 | GetDefaultRequest gdr = (GetDefaultRequest) r; | ||
313 | Ego ego = getEgoForKey(m.privateKey); | ||
314 | if (null != ego) | ||
315 | gdr.identityCallback.onEgo(ego); | ||
316 | } | ||
317 | |||
318 | public void visit(final UpdateListMessage m) { | ||
319 | if (m.endOfList != 0) { | ||
320 | identityListCallback.onListEnd(); | ||
321 | return; | ||
322 | } | ||
323 | if (m.nameLength == 0) { | ||
324 | Ego e = getEgoForKey(m.privateKey); | ||
325 | if (null != e) { | ||
326 | knownEgos.remove(e); | ||
327 | } | ||
328 | identityListCallback.onEgoDelete(e); | ||
329 | } else { | ||
330 | Ego existingEgo = getEgoForKey(m.privateKey); | ||
331 | if (existingEgo == null) { | ||
332 | Ego ego = new Ego(m.egoName, m.privateKey); | ||
333 | knownEgos.add(ego); | ||
334 | identityListCallback.onEgoAdd(ego); | ||
335 | } else { | ||
336 | // rename | ||
337 | String oldName = existingEgo.name; | ||
338 | existingEgo.name = m.egoName; | ||
339 | identityListCallback.onEgoRename(oldName, existingEgo); | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | } | ||
diff --git a/src/main/java/org/gnunet/identity/IdentityCallback.java b/src/main/java/org/gnunet/identity/IdentityCallback.java new file mode 100644 index 0000000..b952c41 --- /dev/null +++ b/src/main/java/org/gnunet/identity/IdentityCallback.java | |||
@@ -0,0 +1,27 @@ | |||
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.identity; | ||
22 | |||
23 | public interface IdentityCallback { | ||
24 | void onEgo(Identity.Ego ego); | ||
25 | |||
26 | void onError(String errorMessage); | ||
27 | } | ||
diff --git a/src/main/java/org/gnunet/identity/IdentityContinuation.java b/src/main/java/org/gnunet/identity/IdentityContinuation.java new file mode 100644 index 0000000..52de2d0 --- /dev/null +++ b/src/main/java/org/gnunet/identity/IdentityContinuation.java | |||
@@ -0,0 +1,26 @@ | |||
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.identity; | ||
22 | |||
23 | public interface IdentityContinuation { | ||
24 | void onError(String errorMessage); | ||
25 | void onDone(); | ||
26 | } | ||
diff --git a/src/main/java/org/gnunet/identity/IdentityListCallback.java b/src/main/java/org/gnunet/identity/IdentityListCallback.java new file mode 100644 index 0000000..afe251d --- /dev/null +++ b/src/main/java/org/gnunet/identity/IdentityListCallback.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.identity; | ||
22 | |||
23 | |||
24 | public interface IdentityListCallback { | ||
25 | void onEgoAdd(Identity.Ego ego); | ||
26 | void onEgoDelete(Identity.Ego ego); | ||
27 | void onEgoRename(String oldName, Identity.Ego ego); | ||
28 | void onListEnd(); | ||
29 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/CreateRequestMessage.java b/src/main/java/org/gnunet/identity/messages/CreateRequestMessage.java new file mode 100644 index 0000000..475100c --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/CreateRequestMessage.java | |||
@@ -0,0 +1,63 @@ | |||
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.identity.messages; | ||
42 | |||
43 | import org.gnunet.construct.NestedMessage; | ||
44 | import org.gnunet.construct.UInt16; | ||
45 | import org.gnunet.construct.UnionCase; | ||
46 | import org.gnunet.construct.ZeroTerminatedString; | ||
47 | import org.gnunet.util.CryptoECC; | ||
48 | import org.gnunet.util.GnunetMessage; | ||
49 | |||
50 | @UnionCase(629) | ||
51 | public class CreateRequestMessage implements GnunetMessage.Body { | ||
52 | /** | ||
53 | * Length of the name, INCLUDING the 0-terminator. | ||
54 | */ | ||
55 | @UInt16 | ||
56 | public int nameLength; | ||
57 | @UInt16 | ||
58 | public int reserved; | ||
59 | @NestedMessage | ||
60 | public CryptoECC.PrivateKey privateKey; | ||
61 | @ZeroTerminatedString | ||
62 | public String name; | ||
63 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/DeleteMessage.java b/src/main/java/org/gnunet/identity/messages/DeleteMessage.java new file mode 100644 index 0000000..7c48c1f --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/DeleteMessage.java | |||
@@ -0,0 +1,36 @@ | |||
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.identity.messages; | ||
22 | |||
23 | import org.gnunet.construct.UInt16; | ||
24 | import org.gnunet.construct.UnionCase; | ||
25 | import org.gnunet.construct.ZeroTerminatedString; | ||
26 | import org.gnunet.util.GnunetMessage; | ||
27 | |||
28 | @UnionCase(631) | ||
29 | public class DeleteMessage implements GnunetMessage.Body { | ||
30 | @UInt16 | ||
31 | public int nameLength; | ||
32 | @UInt16 | ||
33 | public int reserved; | ||
34 | @ZeroTerminatedString | ||
35 | public String name; | ||
36 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/GetDefaultMessage.java b/src/main/java/org/gnunet/identity/messages/GetDefaultMessage.java new file mode 100644 index 0000000..fab5f33 --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/GetDefaultMessage.java | |||
@@ -0,0 +1,98 @@ | |||
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 | /* | ||
62 | This file is part of GNUnet. | ||
63 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
64 | |||
65 | GNUnet is free software; you can redistribute it and/or modify | ||
66 | it under the terms of the GNU General Public License as published | ||
67 | by the Free Software Foundation; either version 3, or (at your | ||
68 | option) any later version. | ||
69 | |||
70 | GNUnet is distributed in the hope that it will be useful, but | ||
71 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
72 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
73 | General Public License for more details. | ||
74 | |||
75 | You should have received a copy of the GNU General Public License | ||
76 | along with GNUnet; see the file COPYING. If not, write to the | ||
77 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
78 | Boston, MA 02111-1307, USA. | ||
79 | */ | ||
80 | |||
81 | package org.gnunet.identity.messages; | ||
82 | |||
83 | import org.gnunet.construct.NestedMessage; | ||
84 | import org.gnunet.construct.UInt16; | ||
85 | import org.gnunet.construct.UnionCase; | ||
86 | import org.gnunet.construct.ZeroTerminatedString; | ||
87 | import org.gnunet.util.CryptoECC; | ||
88 | import org.gnunet.util.GnunetMessage; | ||
89 | |||
90 | @UnionCase(627) | ||
91 | public class GetDefaultMessage implements GnunetMessage.Body { | ||
92 | @UInt16 | ||
93 | public int nameLength; | ||
94 | @UInt16 | ||
95 | public int reserved; | ||
96 | @ZeroTerminatedString | ||
97 | public String serviceName; | ||
98 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/RenameMessage.java b/src/main/java/org/gnunet/identity/messages/RenameMessage.java new file mode 100644 index 0000000..a5b9d2e --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/RenameMessage.java | |||
@@ -0,0 +1,58 @@ | |||
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.identity.messages; | ||
42 | |||
43 | import org.gnunet.construct.UInt16; | ||
44 | import org.gnunet.construct.UnionCase; | ||
45 | import org.gnunet.construct.ZeroTerminatedString; | ||
46 | import org.gnunet.util.GnunetMessage; | ||
47 | |||
48 | @UnionCase(630) | ||
49 | public class RenameMessage implements GnunetMessage.Body { | ||
50 | @UInt16 | ||
51 | public int oldNameLength; | ||
52 | @UInt16 | ||
53 | public int newNameLength; | ||
54 | @ZeroTerminatedString | ||
55 | public String oldName; | ||
56 | @ZeroTerminatedString | ||
57 | public String newName; | ||
58 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/ResultCodeMessage.java b/src/main/java/org/gnunet/identity/messages/ResultCodeMessage.java new file mode 100644 index 0000000..c761603 --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/ResultCodeMessage.java | |||
@@ -0,0 +1,121 @@ | |||
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 | /* | ||
62 | This file is part of GNUnet. | ||
63 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
64 | |||
65 | GNUnet is free software; you can redistribute it and/or modify | ||
66 | it under the terms of the GNU General Public License as published | ||
67 | by the Free Software Foundation; either version 3, or (at your | ||
68 | option) any later version. | ||
69 | |||
70 | GNUnet is distributed in the hope that it will be useful, but | ||
71 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
72 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
73 | General Public License for more details. | ||
74 | |||
75 | You should have received a copy of the GNU General Public License | ||
76 | along with GNUnet; see the file COPYING. If not, write to the | ||
77 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
78 | Boston, MA 02111-1307, USA. | ||
79 | */ | ||
80 | |||
81 | /* | ||
82 | This file is part of GNUnet. | ||
83 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
84 | |||
85 | GNUnet is free software; you can redistribute it and/or modify | ||
86 | it under the terms of the GNU General Public License as published | ||
87 | by the Free Software Foundation; either version 3, or (at your | ||
88 | option) any later version. | ||
89 | |||
90 | GNUnet is distributed in the hope that it will be useful, but | ||
91 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
92 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
93 | General Public License for more details. | ||
94 | |||
95 | You should have received a copy of the GNU General Public License | ||
96 | along with GNUnet; see the file COPYING. If not, write to the | ||
97 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
98 | Boston, MA 02111-1307, USA. | ||
99 | */ | ||
100 | |||
101 | package org.gnunet.identity.messages; | ||
102 | |||
103 | import org.gnunet.construct.*; | ||
104 | import org.gnunet.util.CryptoECC; | ||
105 | import org.gnunet.util.GnunetMessage; | ||
106 | |||
107 | /** | ||
108 | * Answer from service to client about last operation; | ||
109 | * GET_DEFAULT maybe answered with this message on failure; | ||
110 | * CREATE and RENAME will always be answered with this message. | ||
111 | */ | ||
112 | @UnionCase(625) | ||
113 | public class ResultCodeMessage implements GnunetMessage.Body { | ||
114 | /** | ||
115 | * Result code, currently unused. | ||
116 | */ | ||
117 | @UInt32 | ||
118 | public int resultCode; | ||
119 | @ZeroTerminatedString(optional = true) | ||
120 | public String errorMessage; | ||
121 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/SetDefaultMessage.java b/src/main/java/org/gnunet/identity/messages/SetDefaultMessage.java new file mode 100644 index 0000000..bcdb233 --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/SetDefaultMessage.java | |||
@@ -0,0 +1,85 @@ | |||
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.identity.messages; | ||
62 | |||
63 | import org.gnunet.construct.NestedMessage; | ||
64 | import org.gnunet.construct.UInt16; | ||
65 | import org.gnunet.construct.UnionCase; | ||
66 | import org.gnunet.construct.ZeroTerminatedString; | ||
67 | import org.gnunet.util.CryptoECC; | ||
68 | import org.gnunet.util.GnunetMessage; | ||
69 | |||
70 | |||
71 | /** | ||
72 | * Used from service to client as a result to the GET_DEFAULT | ||
73 | * message, used from client to service to SET_DEFAULT. | ||
74 | */ | ||
75 | @UnionCase(628) | ||
76 | public class SetDefaultMessage implements GnunetMessage.Body { | ||
77 | @UInt16 | ||
78 | public int nameLength; | ||
79 | @UInt16 | ||
80 | public int reserved; | ||
81 | @NestedMessage | ||
82 | public CryptoECC.PrivateKey privateKey; | ||
83 | @ZeroTerminatedString | ||
84 | public String serviceName; | ||
85 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/StartMessage.java b/src/main/java/org/gnunet/identity/messages/StartMessage.java new file mode 100644 index 0000000..b8fbbee --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/StartMessage.java | |||
@@ -0,0 +1,73 @@ | |||
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.identity.messages; | ||
62 | |||
63 | import org.gnunet.construct.NestedMessage; | ||
64 | import org.gnunet.construct.UInt16; | ||
65 | import org.gnunet.construct.UnionCase; | ||
66 | import org.gnunet.construct.ZeroTerminatedString; | ||
67 | import org.gnunet.util.CryptoECC; | ||
68 | import org.gnunet.util.GnunetMessage; | ||
69 | |||
70 | @UnionCase(624) | ||
71 | public class StartMessage implements GnunetMessage.Body { | ||
72 | |||
73 | } | ||
diff --git a/src/main/java/org/gnunet/identity/messages/UpdateListMessage.java b/src/main/java/org/gnunet/identity/messages/UpdateListMessage.java new file mode 100644 index 0000000..f1fb8ab --- /dev/null +++ b/src/main/java/org/gnunet/identity/messages/UpdateListMessage.java | |||
@@ -0,0 +1,104 @@ | |||
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 | /* | ||
62 | This file is part of GNUnet. | ||
63 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
64 | |||
65 | GNUnet is free software; you can redistribute it and/or modify | ||
66 | it under the terms of the GNU General Public License as published | ||
67 | by the Free Software Foundation; either version 3, or (at your | ||
68 | option) any later version. | ||
69 | |||
70 | GNUnet is distributed in the hope that it will be useful, but | ||
71 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
72 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
73 | General Public License for more details. | ||
74 | |||
75 | You should have received a copy of the GNU General Public License | ||
76 | along with GNUnet; see the file COPYING. If not, write to the | ||
77 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
78 | Boston, MA 02111-1307, USA. | ||
79 | */ | ||
80 | |||
81 | package org.gnunet.identity.messages; | ||
82 | |||
83 | import org.gnunet.construct.NestedMessage; | ||
84 | import org.gnunet.construct.UInt16; | ||
85 | import org.gnunet.construct.UnionCase; | ||
86 | import org.gnunet.construct.ZeroTerminatedString; | ||
87 | import org.gnunet.util.CryptoECC; | ||
88 | import org.gnunet.util.GnunetMessage; | ||
89 | |||
90 | |||
91 | /** | ||
92 | * Service informs client about status of a pseudonym. | ||
93 | */ | ||
94 | @UnionCase(626) | ||
95 | public class UpdateListMessage implements GnunetMessage.Body{ | ||
96 | @UInt16 | ||
97 | public int nameLength; | ||
98 | @UInt16 | ||
99 | public int endOfList; | ||
100 | @NestedMessage | ||
101 | public CryptoECC.PrivateKey privateKey; | ||
102 | @ZeroTerminatedString | ||
103 | public String egoName; | ||
104 | } | ||
diff --git a/src/main/java/org/gnunet/mq/MessageQueue.java b/src/main/java/org/gnunet/mq/MessageQueue.java index cab1003..85abd67 100644 --- a/src/main/java/org/gnunet/mq/MessageQueue.java +++ b/src/main/java/org/gnunet/mq/MessageQueue.java | |||
@@ -73,6 +73,10 @@ public abstract class MessageQueue { | |||
73 | trySubmitNext(); | 73 | trySubmitNext(); |
74 | } | 74 | } |
75 | 75 | ||
76 | /** | ||
77 | * Report to the message queue that the message has been sent irrevocably. | ||
78 | * Only up to calling reportMessageSend, a message can be canceled. | ||
79 | */ | ||
76 | protected void reportMessageSent() { | 80 | protected void reportMessageSent() { |
77 | if (null == currentEnvelope) | 81 | if (null == currentEnvelope) |
78 | throw new AssertionError(); | 82 | throw new AssertionError(); |
diff --git a/src/main/java/org/gnunet/testbed/Controller.java b/src/main/java/org/gnunet/testbed/Controller.java index 3a4c540..939f855 100644 --- a/src/main/java/org/gnunet/testbed/Controller.java +++ b/src/main/java/org/gnunet/testbed/Controller.java | |||
@@ -352,20 +352,16 @@ public class Controller { | |||
352 | * @param host host to run the controller on; This should be the same host if | 352 | * @param host host to run the controller on; This should be the same host if |
353 | * the controller was previously started with | 353 | * the controller was previously started with |
354 | * GNUNET_TESTBED_controller_start() | 354 | * GNUNET_TESTBED_controller_start() |
355 | * @param event_mask bit mask with set of events to call 'cc' for; | ||
356 | * or-ed values of "1LL" shifted by the | ||
357 | * respective 'enum GNUNET_TESTBED_EventType' | ||
358 | * (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) | ...") | ||
359 | * @param cb controller callback to invoke on events | ||
360 | */ | 355 | */ |
361 | public Controller(Host host, long event_mask, ControllerEventCallback cb) { | 356 | public Controller(Host host) { |
362 | this.host = host; | 357 | this.host = host; |
363 | client = new Client("testbed", host.cfg); | 358 | client = new Client("testbed", host.cfg); |
364 | client.installReceiver(new ControllerMessageReceiver()); | 359 | client.installReceiver(new ControllerMessageReceiver()); |
365 | requests = new MatchingRequestContainer<Long, OperationRequest>(client); | 360 | requests = new MatchingRequestContainer<Long, OperationRequest>(client); |
366 | 361 | ||
367 | ControllerInitMessage m = new ControllerInitMessage(); | 362 | ControllerInitMessage m = new ControllerInitMessage(); |
368 | m.event_mask = event_mask; | 363 | // we are interested in all events |
364 | m.event_mask = 1 | 2 | 4 | 8 | 16; | ||
369 | m.controler_hostname = (host.hostname == null) ? "127.0.0.1" : host.hostname; | 365 | m.controler_hostname = (host.hostname == null) ? "127.0.0.1" : host.hostname; |
370 | m.host_id = host.id; | 366 | m.host_id = host.id; |
371 | client.send(m); | 367 | client.send(m); |
@@ -500,7 +496,6 @@ public class Controller { | |||
500 | return requests.addRequest(r.operationId, r); | 496 | return requests.addRequest(r.operationId, r); |
501 | } | 497 | } |
502 | 498 | ||
503 | |||
504 | public Cancelable requestInformation(PeerInformationCallback cb) { | 499 | public Cancelable requestInformation(PeerInformationCallback cb) { |
505 | PeerInformationRequest r = new PeerInformationRequest(this, cb); | 500 | PeerInformationRequest r = new PeerInformationRequest(this, cb); |
506 | return requests.addRequest(r.operationId, r); | 501 | return requests.addRequest(r.operationId, r); |
diff --git a/src/main/java/org/gnunet/testbed/callbacks/ControllerEventCallback.java b/src/main/java/org/gnunet/testbed/callbacks/ControllerEventCallback.java deleted file mode 100644 index 573c38a..0000000 --- a/src/main/java/org/gnunet/testbed/callbacks/ControllerEventCallback.java +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | package org.gnunet.testbed.callbacks; | ||
2 | |||
3 | |||
4 | |||
5 | public abstract class ControllerEventCallback { | ||
6 | void onPeerStart() { | ||
7 | throw new AssertionError("event not handled"); | ||
8 | } | ||
9 | void onPeerStop() { | ||
10 | throw new AssertionError("event not handled"); | ||
11 | } | ||
12 | void onPeerConnect() { | ||
13 | throw new AssertionError("event not handled"); | ||
14 | } | ||
15 | void onPeerDisconnect() { | ||
16 | throw new AssertionError("event not handled"); | ||
17 | } | ||
18 | void onOperationFinished() { | ||
19 | throw new AssertionError("event not handled"); | ||
20 | } | ||
21 | } | ||
diff --git a/src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java b/src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java index b009f58..670da41 100644 --- a/src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java +++ b/src/main/java/org/gnunet/testbed/messages/PeerInformationMessage.java | |||
@@ -48,9 +48,6 @@ public class PeerInformationMessage implements GnunetMessage.Body { | |||
48 | @UInt16 | 48 | @UInt16 |
49 | public int uncompressedConfigSize; | 49 | public int uncompressedConfigSize; |
50 | 50 | ||
51 | @UInt16 | ||
52 | public int pading1; | ||
53 | |||
54 | @FillWith @UInt8 | 51 | @FillWith @UInt8 |
55 | public byte[] compressedConfig; | 52 | public byte[] compressedConfig; |
56 | } | 53 | } |
diff --git a/src/main/java/org/gnunet/util/AbsoluteTime.java b/src/main/java/org/gnunet/util/AbsoluteTime.java index 265abf5..6027198 100644 --- a/src/main/java/org/gnunet/util/AbsoluteTime.java +++ b/src/main/java/org/gnunet/util/AbsoluteTime.java | |||
@@ -23,7 +23,11 @@ package org.gnunet.util; | |||
23 | import org.slf4j.Logger; | 23 | import org.slf4j.Logger; |
24 | import org.slf4j.LoggerFactory; | 24 | import org.slf4j.LoggerFactory; |
25 | 25 | ||
26 | import java.text.ParseException; | ||
27 | import java.text.SimpleDateFormat; | ||
28 | import java.util.Calendar; | ||
26 | import java.util.Date; | 29 | import java.util.Date; |
30 | import java.util.GregorianCalendar; | ||
27 | 31 | ||
28 | /** | 32 | /** |
29 | * A specific point in time. | 33 | * A specific point in time. |
@@ -270,4 +274,46 @@ public class AbsoluteTime implements Comparable<AbsoluteTime> { | |||
270 | public long getSeconds() { | 274 | public long getSeconds() { |
271 | return abs_value_us / (1000 * 1000); | 275 | return abs_value_us / (1000 * 1000); |
272 | } | 276 | } |
277 | |||
278 | public static AbsoluteTime fromSeconds(long stamp) { | ||
279 | return new AbsoluteTime(stamp * 1000 * 1000); | ||
280 | } | ||
281 | |||
282 | public String toFancyString() { | ||
283 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); | ||
284 | return sdf.format(new Date(getMilliseconds())); | ||
285 | } | ||
286 | |||
287 | private long getMilliseconds() { | ||
288 | return abs_value_us / 1000; | ||
289 | } | ||
290 | |||
291 | public static AbsoluteTime fromString(String s) { | ||
292 | Date date = null; | ||
293 | |||
294 | try { | ||
295 | SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); | ||
296 | date = sdf.parse(s); | ||
297 | return new AbsoluteTime(date.getTime() * 1000); | ||
298 | } catch (ParseException e) { | ||
299 | // try next format | ||
300 | } | ||
301 | |||
302 | try { | ||
303 | SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm"); | ||
304 | date = sdf.parse(s); | ||
305 | return new AbsoluteTime(date.getTime() * 1000); | ||
306 | } catch (ParseException e) { | ||
307 | // try next format | ||
308 | } | ||
309 | |||
310 | try { | ||
311 | SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd"); | ||
312 | date = sdf.parse(s); | ||
313 | return new AbsoluteTime(date.getTime() * 1000); | ||
314 | } catch (ParseException e) { | ||
315 | // try next format | ||
316 | } | ||
317 | return null; | ||
318 | } | ||
273 | } | 319 | } |
diff --git a/src/main/java/org/gnunet/util/Connection.java b/src/main/java/org/gnunet/util/Connection.java index 1c569c4..c8b6a48 100644 --- a/src/main/java/org/gnunet/util/Connection.java +++ b/src/main/java/org/gnunet/util/Connection.java | |||
@@ -31,6 +31,7 @@ import java.io.IOException; | |||
31 | import java.net.InetAddress; | 31 | import java.net.InetAddress; |
32 | import java.net.InetSocketAddress; | 32 | import java.net.InetSocketAddress; |
33 | import java.nio.ByteBuffer; | 33 | import java.nio.ByteBuffer; |
34 | import java.nio.channels.SelectionKey; | ||
34 | import java.nio.channels.SocketChannel; | 35 | import java.nio.channels.SocketChannel; |
35 | import java.nio.channels.spi.SelectorProvider; | 36 | import java.nio.channels.spi.SelectorProvider; |
36 | import java.util.LinkedList; | 37 | import java.util.LinkedList; |
@@ -101,7 +102,7 @@ public class Connection { | |||
101 | /** | 102 | /** |
102 | * Timeout task for the connect notify. | 103 | * Timeout task for the connect notify. |
103 | */ | 104 | */ |
104 | private Scheduler.TaskConfiguration notifyConnectedTimeout; | 105 | private Scheduler.TaskIdentifier notifyConnectedTimeout; |
105 | 106 | ||
106 | /** | 107 | /** |
107 | * Continuation to call when connected | 108 | * Continuation to call when connected |
@@ -159,7 +160,7 @@ public class Connection { | |||
159 | private MessageReceiver receiver; | 160 | private MessageReceiver receiver; |
160 | private RelativeTime timeout; | 161 | private RelativeTime timeout; |
161 | private GnunetMessage.Header msgh = null; | 162 | private GnunetMessage.Header msgh = null; |
162 | private Scheduler.TaskConfiguration recvTask = null; | 163 | private Scheduler.TaskIdentifier recvTask = null; |
163 | private boolean finished = false; | 164 | private boolean finished = false; |
164 | // is this receiver actively working? if not, the connection process has to kick off the receiver | 165 | // is this receiver actively working? if not, the connection process has to kick off the receiver |
165 | // (or select behaves badly) | 166 | // (or select behaves badly) |
@@ -367,7 +368,7 @@ public class Connection { | |||
367 | // of a message, only the max. wait time before transmission. | 368 | // of a message, only the max. wait time before transmission. |
368 | // cancel must be called on the transmitTask if we disconnect | 369 | // cancel must be called on the transmitTask if we disconnect |
369 | Scheduler.TaskConfiguration tc = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, this); | 370 | Scheduler.TaskConfiguration tc = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, this); |
370 | tc.selectWrite(connectionChannel); | 371 | tc.addSelectEvent(connectionChannel, SelectionKey.OP_WRITE); |
371 | this.transmitTask = tc.schedule(); | 372 | this.transmitTask = tc.schedule(); |
372 | } | 373 | } |
373 | 374 | ||
@@ -450,7 +451,7 @@ public class Connection { | |||
450 | return; | 451 | return; |
451 | } | 452 | } |
452 | 453 | ||
453 | tc.selectConnect(channel); | 454 | tc.addSelectEvent(channel, SelectionKey.OP_CONNECT); |
454 | 455 | ||
455 | addressProbe.connectTask = tc.schedule(); | 456 | addressProbe.connectTask = tc.schedule(); |
456 | } | 457 | } |
diff --git a/src/main/java/org/gnunet/util/CryptoECC.java b/src/main/java/org/gnunet/util/CryptoECC.java index d27a2a4..a02cf70 100644 --- a/src/main/java/org/gnunet/util/CryptoECC.java +++ b/src/main/java/org/gnunet/util/CryptoECC.java | |||
@@ -24,17 +24,16 @@ 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; | ||
28 | import java.io.IOError; | 27 | import java.io.IOError; |
29 | import java.io.IOException; | 28 | import java.io.IOException; |
30 | import java.math.BigInteger; | 29 | import java.math.BigInteger; |
31 | import java.nio.ByteBuffer; | 30 | import java.nio.ByteBuffer; |
32 | import java.nio.file.Files; | 31 | import java.nio.file.Files; |
33 | import java.nio.file.OpenOption; | ||
34 | import java.nio.file.StandardOpenOption; | 32 | import java.nio.file.StandardOpenOption; |
35 | import java.security.MessageDigest; | 33 | import java.security.MessageDigest; |
36 | import java.security.NoSuchAlgorithmException; | 34 | import java.security.NoSuchAlgorithmException; |
37 | import java.security.SecureRandom; | 35 | import java.security.SecureRandom; |
36 | import java.util.Arrays; | ||
38 | import java.util.Random; | 37 | import java.util.Random; |
39 | 38 | ||
40 | /** | 39 | /** |
@@ -42,7 +41,6 @@ import java.util.Random; | |||
42 | * Original Java version written and placed into the public domain by k3d3 (https://github.com/k3d3/ed25519-java). | 41 | * Original Java version written and placed into the public domain by k3d3 (https://github.com/k3d3/ed25519-java). |
43 | */ | 42 | */ |
44 | public class CryptoECC { | 43 | public class CryptoECC { |
45 | |||
46 | /** | 44 | /** |
47 | * Private ECC key. | 45 | * Private ECC key. |
48 | */ | 46 | */ |
@@ -91,7 +89,7 @@ public class CryptoECC { | |||
91 | /** | 89 | /** |
92 | * Public ECC key. | 90 | * Public ECC key. |
93 | */ | 91 | */ |
94 | public static final class PublicKey implements Message { | 92 | public static final class PublicSignKey implements Message { |
95 | /** | 93 | /** |
96 | * x-coordinate of the point on the curve. | 94 | * x-coordinate of the point on the curve. |
97 | * The number is stored as little endian. | 95 | * The number is stored as little endian. |
@@ -116,8 +114,8 @@ public class CryptoECC { | |||
116 | return new BigInteger[]{decodeint(x), decodeint(y)}; | 114 | return new BigInteger[]{decodeint(x), decodeint(y)}; |
117 | } | 115 | } |
118 | 116 | ||
119 | public static PublicKey fromString(String s) { | 117 | public static PublicSignKey fromString(String s) { |
120 | PublicKey pk = new PublicKey(); | 118 | PublicSignKey pk = new PublicSignKey(); |
121 | byte[] data = Strings.stringToData(s, 32); | 119 | byte[] data = Strings.stringToData(s, 32); |
122 | if (null == data) | 120 | if (null == data) |
123 | return null; | 121 | return null; |
@@ -126,6 +124,26 @@ public class CryptoECC { | |||
126 | pk.y = encodeint(point[1]); | 124 | pk.y = encodeint(point[1]); |
127 | return pk; | 125 | return pk; |
128 | } | 126 | } |
127 | |||
128 | @Override | ||
129 | public boolean equals(Object o) { | ||
130 | if (this == o) return true; | ||
131 | if (o == null || getClass() != o.getClass()) return false; | ||
132 | |||
133 | PublicSignKey that = (PublicSignKey) o; | ||
134 | |||
135 | if (!Arrays.equals(x, that.x)) return false; | ||
136 | if (!Arrays.equals(y, that.y)) return false; | ||
137 | |||
138 | return true; | ||
139 | } | ||
140 | |||
141 | @Override | ||
142 | public int hashCode() { | ||
143 | int result = Arrays.hashCode(x); | ||
144 | result = 31 * result + Arrays.hashCode(y); | ||
145 | return result; | ||
146 | } | ||
129 | } | 147 | } |
130 | 148 | ||
131 | /** | 149 | /** |
@@ -336,10 +354,10 @@ public class CryptoECC { | |||
336 | * @param sk private key | 354 | * @param sk private key |
337 | * @return public key derived from 'sk' | 355 | * @return public key derived from 'sk' |
338 | */ | 356 | */ |
339 | static public PublicKey computePublicKey(PrivateKey sk) { | 357 | static public PublicSignKey computePublicKey(PrivateKey sk) { |
340 | BigInteger a = computePublicKeyCoefficient(sk); | 358 | BigInteger a = computePublicKeyCoefficient(sk); |
341 | BigInteger[] A = scalarmult(B, a); | 359 | BigInteger[] A = scalarmult(B, a); |
342 | PublicKey publicKey = new PublicKey(); | 360 | PublicSignKey publicKey = new PublicSignKey(); |
343 | publicKey.x = encodeint(A[0]); | 361 | publicKey.x = encodeint(A[0]); |
344 | publicKey.y = encodeint(A[1]); | 362 | publicKey.y = encodeint(A[1]); |
345 | return publicKey; | 363 | return publicKey; |
@@ -370,7 +388,7 @@ public class CryptoECC { | |||
370 | * parameter for performance reasons | 388 | * parameter for performance reasons |
371 | * @return a signature on m | 389 | * @return a signature on m |
372 | */ | 390 | */ |
373 | public static Signature sign(byte[] m, PrivateKey sk, PublicKey pk) { | 391 | public static Signature sign(byte[] m, PrivateKey sk, PublicSignKey pk) { |
374 | byte[] compressed_pk = encodepoint(new BigInteger[]{decodeint(pk.x), decodeint(pk.y)}); | 392 | byte[] compressed_pk = encodepoint(new BigInteger[]{decodeint(pk.x), decodeint(pk.y)}); |
375 | byte[] h = sha512.digest(sk.d); | 393 | byte[] h = sha512.digest(sk.d); |
376 | BigInteger a = BigInteger.valueOf(2).pow(b-2); | 394 | BigInteger a = BigInteger.valueOf(2).pow(b-2); |
@@ -453,7 +471,7 @@ public class CryptoECC { | |||
453 | * @param pk public key of the signature creator | 471 | * @param pk public key of the signature creator |
454 | * @return whether the signature is valid | 472 | * @return whether the signature is valid |
455 | */ | 473 | */ |
456 | public static boolean verify(Signature sig, byte[] m, PublicKey pk) { | 474 | public static boolean verify(Signature sig, byte[] m, PublicSignKey pk) { |
457 | BigInteger[] R = decodepoint(sig.r); | 475 | BigInteger[] R = decodepoint(sig.r); |
458 | BigInteger[] A = new BigInteger[]{decodeint(pk.x), decodeint(pk.y)}; | 476 | BigInteger[] A = new BigInteger[]{decodeint(pk.x), decodeint(pk.y)}; |
459 | BigInteger S = decodeint(sig.s); | 477 | BigInteger S = decodeint(sig.s); |
@@ -472,7 +490,7 @@ public class CryptoECC { | |||
472 | * @param publicKey public key to use for the ECDH (yG) | 490 | * @param publicKey public key to use for the ECDH (yG) |
473 | * @return key material (xyG) | 491 | * @return key material (xyG) |
474 | */ | 492 | */ |
475 | public static HashCode ecdh(PrivateKey privateKey, PublicKey publicKey) { | 493 | public static HashCode ecdh(PrivateKey privateKey, PublicSignKey publicKey) { |
476 | BigInteger[] publicPoint = new BigInteger[]{decodeint(publicKey.x), decodeint(publicKey.y)}; | 494 | BigInteger[] publicPoint = new BigInteger[]{decodeint(publicKey.x), decodeint(publicKey.y)}; |
477 | BigInteger coeff = computePublicKeyCoefficient(privateKey); | 495 | BigInteger coeff = computePublicKeyCoefficient(privateKey); |
478 | BigInteger[] R = scalarmult(publicPoint, coeff); | 496 | BigInteger[] R = scalarmult(publicPoint, coeff); |
@@ -480,4 +498,16 @@ public class CryptoECC { | |||
480 | sha512.update(R[0].toByteArray()); | 498 | sha512.update(R[0].toByteArray()); |
481 | return new HashCode(sha512.digest(R[1].toByteArray())); | 499 | return new HashCode(sha512.digest(R[1].toByteArray())); |
482 | } | 500 | } |
501 | |||
502 | /** | ||
503 | * Get the shared private key we use for anonymous users. | ||
504 | * | ||
505 | * @return "anonymous" private key | ||
506 | */ | ||
507 | public static PrivateKey getAnonymous() { | ||
508 | PrivateKey privateKey = new PrivateKey(); | ||
509 | privateKey.d = encodeint(BigInteger.ONE); | ||
510 | return privateKey; | ||
511 | } | ||
512 | |||
483 | } | 513 | } |
diff --git a/src/main/java/org/gnunet/util/Helper.java b/src/main/java/org/gnunet/util/Helper.java index ea757f6..64d4aaa 100644 --- a/src/main/java/org/gnunet/util/Helper.java +++ b/src/main/java/org/gnunet/util/Helper.java | |||
@@ -19,23 +19,18 @@ | |||
19 | */ | 19 | */ |
20 | package org.gnunet.util; | 20 | package org.gnunet.util; |
21 | 21 | ||
22 | |||
22 | import org.gnunet.construct.Construct; | 23 | import org.gnunet.construct.Construct; |
23 | import org.gnunet.construct.Message; | ||
24 | import org.gnunet.construct.MessageLoader; | ||
25 | import org.gnunet.construct.ProtocolViolationException; | ||
26 | import org.gnunet.mq.Envelope; | 24 | import org.gnunet.mq.Envelope; |
27 | import org.gnunet.mq.MessageQueue; | 25 | import org.gnunet.mq.MessageQueue; |
28 | import org.slf4j.Logger; | 26 | import org.slf4j.Logger; |
29 | import org.slf4j.LoggerFactory; | 27 | import org.slf4j.LoggerFactory; |
30 | 28 | ||
31 | import java.io.File; | 29 | import java.io.ByteArrayOutputStream; |
32 | import java.io.IOError; | 30 | import java.io.IOError; |
33 | import java.io.IOException; | 31 | import java.io.IOException; |
34 | import java.nio.Buffer; | ||
35 | import java.nio.ByteBuffer; | 32 | import java.nio.ByteBuffer; |
36 | import java.nio.channels.Channels; | 33 | import java.nio.channels.*; |
37 | import java.nio.channels.ReadableByteChannel; | ||
38 | import java.util.EnumSet; | ||
39 | import java.util.LinkedList; | 34 | import java.util.LinkedList; |
40 | import java.util.List; | 35 | import java.util.List; |
41 | 36 | ||
@@ -50,145 +45,103 @@ public class Helper extends MessageQueue { | |||
50 | private final ProcessBuilder processBuilder; | 45 | private final ProcessBuilder processBuilder; |
51 | private final RunaboutMessageReceiver receiver; | 46 | private final RunaboutMessageReceiver receiver; |
52 | private Process process; | 47 | private Process process; |
53 | private volatile GnunetMessage.Body writeMessage; | 48 | |
54 | private WriteThread writeThread; | 49 | private WriteThread writeThread; |
55 | private ReadThread readThread; | 50 | private ReadThread readThread; |
51 | |||
52 | private Scheduler.TaskConfiguration writeTaskConfig; | ||
53 | private Scheduler.TaskIdentifier writeTaskId; | ||
54 | |||
55 | private Scheduler.TaskConfiguration readTaskConfig; | ||
56 | private Scheduler.TaskIdentifier readTaskId; | ||
57 | |||
58 | private ByteBuffer writeBuffer = ByteBuffer.allocate(1024); | ||
59 | |||
60 | private MessageStreamTokenizer mst; | ||
61 | |||
62 | private boolean killed; | ||
63 | |||
64 | |||
56 | /** | 65 | /** |
57 | * Task that guarantees scheduler lifeness while the helper process | 66 | * Thread that writes data from a pipe to the helper process. |
58 | * is running. | ||
59 | */ | 67 | */ |
60 | private Cancelable lifenessTask; | ||
61 | |||
62 | private final class WriteThread extends Thread { | 68 | private final class WriteThread extends Thread { |
69 | final Pipe pipe; | ||
70 | public WriteThread() { | ||
71 | try { | ||
72 | pipe = Pipe.open(); | ||
73 | } catch (IOException e) { | ||
74 | throw new RuntimeException("JVM does not support pipes"); | ||
75 | } | ||
76 | } | ||
63 | @Override | 77 | @Override |
64 | public void run() { | 78 | public void run() { |
65 | logger.debug("in write thread"); | 79 | WritableByteChannel channel = Channels.newChannel(process.getOutputStream()); |
66 | GnunetMessage.Body msg; | 80 | ByteBuffer buffer = ByteBuffer.allocate(1024); |
67 | while (true) { | 81 | while (true) { |
68 | synchronized (Helper.this) { | 82 | buffer.clear(); |
69 | while (writeMessage == null) { | ||
70 | try { | ||
71 | Helper.this.wait(); | ||
72 | } catch (InterruptedException e) { | ||
73 | // do nothing | ||
74 | } | ||
75 | } | ||
76 | // we now have a message we can send | ||
77 | msg = writeMessage; | ||
78 | writeMessage = null; | ||
79 | // somebody can set the next send message | ||
80 | } | ||
81 | logger.debug("helper got message"); | ||
82 | GnunetMessage gm = GnunetMessage.fromBody(msg); | ||
83 | byte[] data = Construct.toBinary(gm); | ||
84 | try { | 83 | try { |
85 | process.getOutputStream().write(data); | 84 | logger.debug("waiting for readable pipe in thread"); |
86 | process.getOutputStream().flush(); | 85 | int n = pipe.source().read(buffer); |
86 | if (n == -1) { | ||
87 | logger.debug("write thread pipe closed"); | ||
88 | return; | ||
89 | } | ||
90 | logger.debug("read {} bytes from pipe", n); | ||
91 | buffer.flip(); | ||
92 | while (buffer.hasRemaining()) { | ||
93 | n = channel.write(buffer); | ||
94 | process.getOutputStream().flush(); | ||
95 | logger.debug("written {} bytes to process", n); | ||
96 | } | ||
97 | } catch (ClosedChannelException e) { | ||
98 | logger.debug("channel closed for write thread"); | ||
99 | return; | ||
87 | } catch (IOException e) { | 100 | } catch (IOException e) { |
88 | throw new IOError(e); | 101 | throw new IOError(e); |
89 | } | 102 | } |
90 | logger.debug("helper wrote message, size {}, size in header {}, adding cont", data.length, gm.header.messageSize); | ||
91 | Scheduler.addContinuation(new Scheduler.Task() { | ||
92 | @Override | ||
93 | public void run(Scheduler.RunContext ctx) { | ||
94 | reportMessageSent(); | ||
95 | } | ||
96 | }, EnumSet.noneOf(Scheduler.Reason.class)); | ||
97 | logger.debug("cont added"); | ||
98 | } | 103 | } |
99 | } | 104 | } |
100 | } | 105 | } |
101 | 106 | ||
107 | /** | ||
108 | * Thread that reads data from the helper process and writes it | ||
109 | * to a pipe. | ||
110 | */ | ||
102 | private final class ReadThread extends Thread { | 111 | private final class ReadThread extends Thread { |
103 | private ByteBuffer buffer; | 112 | Pipe pipe; |
104 | ReadableByteChannel channel; | ||
105 | |||
106 | /** | ||
107 | * Read until our buffer is full, or an error occurs. | ||
108 | * | ||
109 | * @return true on success | ||
110 | */ | ||
111 | private boolean fillBuffer() { | ||
112 | while (buffer.hasRemaining()) { | ||
113 | try { | ||
114 | int n = channel.read(buffer); | ||
115 | if (n == -1) { | ||
116 | logger.debug("read eof"); | ||
117 | return false; | ||
118 | } | ||
119 | } catch (IOException e) { | ||
120 | logger.debug("read error"); | ||
121 | return false; | ||
122 | } | ||
123 | } | ||
124 | logger.debug("filled buffer"); | ||
125 | return true; | ||
126 | } | ||
127 | |||
128 | private void scheduleInvokeReceiver(final GnunetMessage.Body body) { | ||
129 | Scheduler.addContinuation(new Scheduler.Task() { | ||
130 | @Override | ||
131 | public void run(Scheduler.RunContext ctx) { | ||
132 | logger.debug("calling receiver with message"); | ||
133 | receiver.process(body); | ||
134 | } | ||
135 | }, EnumSet.noneOf(Scheduler.Reason.class)); | ||
136 | 113 | ||
114 | public ReadThread() { | ||
115 | try { | ||
116 | pipe = Pipe.open(); | ||
117 | } catch (IOException e) { | ||
118 | throw new RuntimeException("JVM does not support pipes"); | ||
119 | } | ||
137 | } | 120 | } |
138 | |||
139 | @Override | 121 | @Override |
140 | public void run() { | 122 | public void run() { |
141 | // allocate just enough for the message header | 123 | byte[] buf = new byte[1024]; |
142 | buffer = ByteBuffer.allocate(4); | ||
143 | channel = Channels.newChannel(process.getInputStream()); | ||
144 | while (true) { | 124 | while (true) { |
145 | // FIXME: use some more general mechanism for reading messages (like a message stream tokenizer) | 125 | int n; |
146 | logger.debug("helper ready to receive message"); | ||
147 | buffer.clear(); | ||
148 | buffer.limit(4); | ||
149 | if (!fillBuffer()) | ||
150 | return; | ||
151 | buffer.rewind(); | ||
152 | GnunetMessage.Header msgh = Construct.parseAs(buffer, GnunetMessage.Header.class); | ||
153 | logger.debug("helper received header of size {}, type {}", msgh.messageSize, msgh.messageType); | ||
154 | if (msgh.messageSize > GnunetMessage.Header.SIZE) { | ||
155 | if (buffer.capacity() < msgh.messageSize) { | ||
156 | ByteBuffer newBuf = ByteBuffer.allocate(msgh.messageSize); | ||
157 | buffer.flip(); | ||
158 | newBuf.put(buffer); | ||
159 | buffer = newBuf; | ||
160 | } | ||
161 | buffer.limit(msgh.messageSize); | ||
162 | if (!fillBuffer()) | ||
163 | return; | ||
164 | } | ||
165 | // we now have a complete message | ||
166 | // prepare for reading again | ||
167 | buffer.flip(); | ||
168 | |||
169 | boolean found = true; | ||
170 | try { | 126 | try { |
171 | MessageLoader.getUnionClass(GnunetMessage.Body.class, msgh.messageType); | 127 | logger.debug("reading from process"); |
172 | } catch (ProtocolViolationException e) { | 128 | n = process.getInputStream().read(buf); |
173 | found = false; | 129 | if (n == -1) { |
130 | logger.debug("reached EOF while reading from process"); | ||
131 | break; | ||
132 | } | ||
133 | logger.debug("read {} bytes from process", n); | ||
134 | ByteBuffer b = ByteBuffer.wrap(buf, 0, n); | ||
135 | while (b.hasRemaining()) { | ||
136 | pipe.sink().write(b); | ||
137 | } | ||
138 | } catch (ClosedChannelException e) { | ||
139 | logger.debug("channel closed for read thread"); | ||
140 | return; | ||
174 | } | 141 | } |
175 | logger.debug("about to parse message"); | 142 | catch (IOException e) { |
176 | if (found) { | 143 | throw new IOError(e); |
177 | logger.debug("found"); | ||
178 | GnunetMessage msg; | ||
179 | msg = Construct.parseAs(buffer, GnunetMessage.class); | ||
180 | logger.debug("parsed"); | ||
181 | scheduleInvokeReceiver(msg.body); | ||
182 | logger.debug("scheduled"); | ||
183 | } else { | ||
184 | logger.debug("not found"); | ||
185 | UnknownMessageBody b = new UnknownMessageBody(); | ||
186 | b.data = buffer.array(); | ||
187 | b.id = msgh.messageType; | ||
188 | scheduleInvokeReceiver(b); | ||
189 | logger.debug("scheduled"); | ||
190 | } | 144 | } |
191 | logger.debug("scheduled call to receiver"); | ||
192 | } | 145 | } |
193 | } | 146 | } |
194 | } | 147 | } |
@@ -203,6 +156,50 @@ public class Helper extends MessageQueue { | |||
203 | return prefix + "/lib/" + "gnunet/" + "libexec/" + binaryName; | 156 | return prefix + "/lib/" + "gnunet/" + "libexec/" + binaryName; |
204 | } | 157 | } |
205 | 158 | ||
159 | |||
160 | private class ReadTask implements Scheduler.Task { | ||
161 | @Override | ||
162 | public void run(Scheduler.RunContext ctx) { | ||
163 | readTaskId = null; | ||
164 | int n = mst.readFrom(readThread.pipe.source()); | ||
165 | if (n != -1 && readThread.pipe.source().isOpen()) { | ||
166 | readTaskId = readTaskConfig.schedule(); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | private class WriteTask implements Scheduler.Task { | ||
172 | @Override | ||
173 | public void run(Scheduler.RunContext ctx) { | ||
174 | writeTaskId = null; | ||
175 | try { | ||
176 | int n = writeThread.pipe.sink().write(writeBuffer); | ||
177 | logger.debug("wrote {} bytes in write task", n); | ||
178 | } catch (IOException e) { | ||
179 | throw new IOError(e); | ||
180 | } | ||
181 | if (writeBuffer.hasRemaining()) { | ||
182 | writeTaskId = writeTaskConfig.schedule(); | ||
183 | } else { | ||
184 | reportMessageSent(); | ||
185 | reportReadyForSubmit(); | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | |||
190 | private class HelperMstCallback implements MstCalllback { | ||
191 | @Override | ||
192 | public void onUnknownMessage(UnknownMessageBody b) { | ||
193 | logger.warn("got unknown message type"); | ||
194 | } | ||
195 | |||
196 | @Override | ||
197 | public void onKnownMessage(GnunetMessage msg) { | ||
198 | logger.debug("processing message from helper"); | ||
199 | receiver.process(msg.body); | ||
200 | } | ||
201 | } | ||
202 | |||
206 | /** | 203 | /** |
207 | * Create and start a new helper process | 204 | * Create and start a new helper process |
208 | * | 205 | * |
@@ -229,21 +226,31 @@ public class Helper extends MessageQueue { | |||
229 | throw new IOError(e); | 226 | throw new IOError(e); |
230 | } | 227 | } |
231 | 228 | ||
232 | lifenessTask = Scheduler.addDelayed(RelativeTime.FOREVER, new Scheduler.Task() { | 229 | mst = new MessageStreamTokenizer(new HelperMstCallback()); |
233 | @Override | ||
234 | public void run(Scheduler.RunContext ctx) { | ||
235 | // do nothing | ||
236 | } | ||
237 | }); | ||
238 | 230 | ||
239 | writeThread = new WriteThread(); | 231 | writeThread = new WriteThread(); |
240 | readThread = new ReadThread(); | 232 | readThread = new ReadThread(); |
241 | 233 | ||
242 | logger.debug("creating helper"); | 234 | logger.debug("creating helper"); |
243 | 235 | ||
236 | try { | ||
237 | readThread.pipe.source().configureBlocking(false); | ||
238 | writeThread.pipe.sink().configureBlocking(false); | ||
239 | } catch (IOException e) { | ||
240 | throw new IOError(e); | ||
241 | } | ||
242 | |||
244 | writeThread.start(); | 243 | writeThread.start(); |
245 | readThread.start(); | 244 | readThread.start(); |
246 | 245 | ||
246 | readTaskConfig = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, new ReadTask()); | ||
247 | readTaskConfig.addSelectEvent(readThread.pipe.source(), SelectionKey.OP_READ); | ||
248 | |||
249 | writeTaskConfig = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, new WriteTask()); | ||
250 | writeTaskConfig.addSelectEvent(writeThread.pipe.sink(), SelectionKey.OP_WRITE); | ||
251 | |||
252 | readTaskId = readTaskConfig.schedule(); | ||
253 | |||
247 | reportReadyForSubmit(); | 254 | reportReadyForSubmit(); |
248 | } | 255 | } |
249 | 256 | ||
@@ -255,7 +262,24 @@ public class Helper extends MessageQueue { | |||
255 | * @return true on success, false on failure | 262 | * @return true on success, false on failure |
256 | */ | 263 | */ |
257 | public boolean kill(boolean softkill) { | 264 | public boolean kill(boolean softkill) { |
258 | lifenessTask.cancel(); | 265 | killed = true; |
266 | if (readTaskId != null) { | ||
267 | readTaskId.cancel(); | ||
268 | readTaskId = null; | ||
269 | } | ||
270 | if (writeTaskId != null) { | ||
271 | writeTaskId.cancel(); | ||
272 | writeTaskId = null; | ||
273 | } | ||
274 | |||
275 | try { | ||
276 | readThread.pipe.source().close(); | ||
277 | readThread.pipe.sink().close(); | ||
278 | writeThread.pipe.source().close(); | ||
279 | writeThread.pipe.sink().close(); | ||
280 | } catch (IOException e) { | ||
281 | throw new IOError(e); | ||
282 | } | ||
259 | if (softkill) { | 283 | if (softkill) { |
260 | try { | 284 | try { |
261 | process.getInputStream().close(); | 285 | process.getInputStream().close(); |
@@ -278,7 +302,6 @@ public class Helper extends MessageQueue { | |||
278 | public boolean waitFor() { | 302 | public boolean waitFor() { |
279 | try { | 303 | try { |
280 | process.waitFor(); | 304 | process.waitFor(); |
281 | process.waitFor(); | ||
282 | } catch (InterruptedException e) { | 305 | } catch (InterruptedException e) { |
283 | return false; | 306 | return false; |
284 | } | 307 | } |
@@ -287,20 +310,27 @@ public class Helper extends MessageQueue { | |||
287 | 310 | ||
288 | @Override | 311 | @Override |
289 | protected void submit(Envelope ev) { | 312 | protected void submit(Envelope ev) { |
313 | if (writeTaskId != null) { | ||
314 | throw new AssertionError(); | ||
315 | } | ||
290 | logger.debug("submitting envelope to helper thread"); | 316 | logger.debug("submitting envelope to helper thread"); |
291 | synchronized (this) { | 317 | final GnunetMessage gm = new GnunetMessage(); |
292 | if (writeMessage != null) | 318 | gm.header = new GnunetMessage.Header(); |
293 | throw new AssertionError("message queue not implemented correctly"); | 319 | gm.body = ev.message; |
294 | writeMessage = ev.message; | 320 | Construct.patch(gm); |
295 | notifyAll(); | 321 | gm.header.messageSize = Construct.getSize(gm); |
322 | if (writeBuffer.capacity() < gm.header.messageSize) { | ||
323 | writeBuffer = ByteBuffer.allocate(gm.header.messageSize); | ||
296 | } | 324 | } |
297 | reportReadyForSubmit(); | 325 | writeBuffer.clear(); |
326 | int n = Construct.write(writeBuffer, gm); | ||
327 | writeBuffer.flip(); | ||
328 | logger.debug("wrote message size {} to write buffer", n); | ||
329 | writeTaskId = writeTaskConfig.schedule(); | ||
298 | } | 330 | } |
299 | 331 | ||
300 | @Override | 332 | @Override |
301 | protected void retract() { | 333 | protected void retract() { |
302 | synchronized (this) { | 334 | throw new UnsupportedOperationException(); |
303 | writeMessage = null; | ||
304 | } | ||
305 | } | 335 | } |
306 | } | 336 | } |
diff --git a/src/main/java/org/gnunet/util/MessageStreamTokenizer.java b/src/main/java/org/gnunet/util/MessageStreamTokenizer.java new file mode 100644 index 0000000..4cf0d03 --- /dev/null +++ b/src/main/java/org/gnunet/util/MessageStreamTokenizer.java | |||
@@ -0,0 +1,122 @@ | |||
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.util; | ||
22 | |||
23 | import org.gnunet.construct.Construct; | ||
24 | import org.gnunet.construct.MessageLoader; | ||
25 | import org.gnunet.construct.ProtocolViolationException; | ||
26 | import org.slf4j.Logger; | ||
27 | import org.slf4j.LoggerFactory; | ||
28 | |||
29 | import java.io.IOError; | ||
30 | import java.io.IOException; | ||
31 | import java.nio.ByteBuffer; | ||
32 | import java.nio.channels.Channel; | ||
33 | import java.nio.channels.ClosedChannelException; | ||
34 | import java.nio.channels.Pipe; | ||
35 | import java.nio.channels.ReadableByteChannel; | ||
36 | |||
37 | /** | ||
38 | * Extract GNUnet messages from a stream of bytes. | ||
39 | */ | ||
40 | public class MessageStreamTokenizer { | ||
41 | private static final Logger logger = LoggerFactory | ||
42 | .getLogger(Service.class); | ||
43 | private MstCalllback mstCalllback; | ||
44 | private ByteBuffer buffer; | ||
45 | GnunetMessage.Header msgh; | ||
46 | public MessageStreamTokenizer(MstCalllback mstCalllback) { | ||
47 | this.mstCalllback = mstCalllback; | ||
48 | // large enough buffer for a message header | ||
49 | this.buffer = ByteBuffer.allocate(4); | ||
50 | } | ||
51 | |||
52 | public void ensureBufferSize() { | ||
53 | if (buffer.capacity() < msgh.messageSize) { | ||
54 | ByteBuffer buf = ByteBuffer.allocate(msgh.messageSize); | ||
55 | buffer.flip(); | ||
56 | buf.put(buffer); | ||
57 | buf.flip(); | ||
58 | buffer = buf; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | public void readAndDispatch() { | ||
63 | Class unionClass = null; | ||
64 | boolean found = true; | ||
65 | |||
66 | try { | ||
67 | unionClass = MessageLoader.getUnionClass(GnunetMessage.Body.class, msgh.messageType); | ||
68 | } catch (ProtocolViolationException e) { | ||
69 | found = false; | ||
70 | } | ||
71 | |||
72 | logger.debug("dispatching message"); | ||
73 | if (found) { | ||
74 | GnunetMessage msg; | ||
75 | try { | ||
76 | msg = Construct.parseAs(buffer, GnunetMessage.class); | ||
77 | } catch (OutOfMemoryError e) { | ||
78 | throw new OutOfMemoryError("oom while parsing " + unionClass); | ||
79 | } | ||
80 | mstCalllback.onKnownMessage(msg); | ||
81 | } else { | ||
82 | UnknownMessageBody b = new UnknownMessageBody(); | ||
83 | b.id = msgh.messageType; | ||
84 | mstCalllback.onUnknownMessage(b); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * Read from a channel into the mst. | ||
90 | * | ||
91 | * @param source channel to read from | ||
92 | * @return -1 on end of stream, number of bytes read otherwise | ||
93 | */ | ||
94 | public int readFrom(ReadableByteChannel source) { | ||
95 | int n; | ||
96 | try { | ||
97 | n = source.read(buffer); | ||
98 | } catch (ClosedChannelException e) { | ||
99 | return -1; | ||
100 | }catch (IOException e) { | ||
101 | throw new IOError(e); | ||
102 | } | ||
103 | if (msgh == null && buffer.position() >= 4) { | ||
104 | logger.debug("got header in mst"); | ||
105 | // remember write position and prepare for reading | ||
106 | int writePos = buffer.position(); | ||
107 | buffer.flip(); | ||
108 | msgh = Construct.parseAs(buffer, GnunetMessage.Header.class); | ||
109 | ensureBufferSize(); | ||
110 | // prepare for writing again, and restore write position | ||
111 | buffer.position(0); | ||
112 | buffer.compact(); | ||
113 | } | ||
114 | if (msgh != null && buffer.position() >= msgh.messageSize) { | ||
115 | buffer.flip(); | ||
116 | readAndDispatch(); | ||
117 | msgh = null; | ||
118 | buffer.compact(); | ||
119 | } | ||
120 | return n; | ||
121 | } | ||
122 | } | ||
diff --git a/src/main/java/org/gnunet/util/MstCalllback.java b/src/main/java/org/gnunet/util/MstCalllback.java new file mode 100644 index 0000000..33abd40 --- /dev/null +++ b/src/main/java/org/gnunet/util/MstCalllback.java | |||
@@ -0,0 +1,27 @@ | |||
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.util; | ||
22 | |||
23 | public interface MstCalllback { | ||
24 | void onUnknownMessage(UnknownMessageBody b); | ||
25 | |||
26 | void onKnownMessage(GnunetMessage msg); | ||
27 | } | ||
diff --git a/src/main/java/org/gnunet/util/Scheduler.java b/src/main/java/org/gnunet/util/Scheduler.java index f5eee8c..1f8d9dc 100644 --- a/src/main/java/org/gnunet/util/Scheduler.java +++ b/src/main/java/org/gnunet/util/Scheduler.java | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | package org.gnunet.util; | 21 | package org.gnunet.util; |
22 | 22 | ||
23 | import com.google.common.collect.Lists; | ||
23 | import org.slf4j.Logger; | 24 | import org.slf4j.Logger; |
24 | import org.slf4j.LoggerFactory; | 25 | import org.slf4j.LoggerFactory; |
25 | 26 | ||
@@ -28,10 +29,13 @@ import java.nio.ByteBuffer; | |||
28 | import java.nio.channels.*; | 29 | import java.nio.channels.*; |
29 | import java.nio.channels.spi.SelectorProvider; | 30 | import java.nio.channels.spi.SelectorProvider; |
30 | import java.util.*; | 31 | import java.util.*; |
31 | import java.util.concurrent.locks.ReentrantLock; | ||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Schedule computations using continuation passing style. | 34 | * Schedule computations using continuation passing style. |
35 | * <p/> | ||
36 | * By design, it is not safe to scheduler tasks from different threads. | ||
37 | * When threads can't be avoided, they should communicate with the scheduler by | ||
38 | * a pipe. | ||
35 | * | 39 | * |
36 | * @author Florian Dold | 40 | * @author Florian Dold |
37 | */ | 41 | */ |
@@ -39,12 +43,10 @@ public class Scheduler { | |||
39 | private static final Logger logger = LoggerFactory | 43 | private static final Logger logger = LoggerFactory |
40 | .getLogger(Scheduler.class); | 44 | .getLogger(Scheduler.class); |
41 | 45 | ||
42 | private static ReentrantLock lock = new ReentrantLock(true); | ||
43 | |||
44 | /** | 46 | /** |
45 | * Task that we are currently executing, or null if no task is currently running. | 47 | * Task that we are currently executing, or null if no task is currently running. |
46 | */ | 48 | */ |
47 | private static TaskConfiguration activeTask = null; | 49 | private static TaskIdentifier activeTask = null; |
48 | 50 | ||
49 | /** | 51 | /** |
50 | * Number of tasks in the ready lists, that is, number of tasks that is ready to run | 52 | * Number of tasks in the ready lists, that is, number of tasks that is ready to run |
@@ -69,21 +71,14 @@ public class Scheduler { | |||
69 | * For every priority, there is a list of tasks that is definitely ready to run. | 71 | * For every priority, there is a list of tasks that is definitely ready to run. |
70 | */ | 72 | */ |
71 | @SuppressWarnings("unchecked") | 73 | @SuppressWarnings("unchecked") |
72 | final private static LinkedList<TaskConfiguration>[] readyLists = new LinkedList[Priority.numberOfPriorities]; | 74 | final private static LinkedList<TaskIdentifier>[] readyLists = new LinkedList[Priority.numberOfPriorities]; |
73 | 75 | ||
74 | static { | 76 | static { |
75 | for (int i = 0; i < Priority.numberOfPriorities; ++i) { | 77 | for (int i = 0; i < Priority.numberOfPriorities; ++i) { |
76 | readyLists[i] = new LinkedList<TaskConfiguration>(); | 78 | readyLists[i] = new LinkedList<TaskIdentifier>(); |
77 | } | 79 | } |
78 | } | 80 | } |
79 | 81 | ||
80 | private static final int EVENT_READ = 0, EVENT_WRITE = 1, EVENT_ACCEPT = 2, EVENT_CONNECT = 3; | ||
81 | private static final int[] eventToInterestOp = new int[]{SelectionKey.OP_READ, SelectionKey.OP_WRITE, | ||
82 | SelectionKey.OP_ACCEPT, SelectionKey.OP_CONNECT}; | ||
83 | private static final Reason[] eventToReason = new Reason[]{Reason.READ_READY, Reason.WRITE_READY, | ||
84 | Reason.ACCEPT_READY, Reason.CONNECT_READY}; | ||
85 | |||
86 | |||
87 | /** | 82 | /** |
88 | * Selector, used to check file descriptors for readiness. | 83 | * Selector, used to check file descriptors for readiness. |
89 | */ | 84 | */ |
@@ -102,37 +97,20 @@ public class Scheduler { | |||
102 | /** | 97 | /** |
103 | * true iff the scheduler is currently running. | 98 | * true iff the scheduler is currently running. |
104 | */ | 99 | */ |
105 | private static boolean scheduler_running = false; | 100 | private static boolean schedulerRunning = false; |
106 | |||
107 | 101 | ||
108 | /** | 102 | /** |
109 | * Pending tasks are waiting for an event. Each pending task has a (possibly infinitely long) | 103 | * Pending tasks are waiting for an event. Each pending task has a (possibly infinitely long) |
110 | * deadline after which the task is executed regardless of the prerequisites. | 104 | * deadline after which the task is executed regardless of the prerequisites. |
111 | */ | 105 | */ |
112 | final private static Queue<TaskConfiguration> pending = new PriorityQueue<TaskConfiguration>(5, new Comparator | 106 | final private static Queue<TaskIdentifier> pending = new PriorityQueue<TaskIdentifier>(5, new Comparator |
113 | <TaskConfiguration>() { | 107 | <TaskIdentifier>() { |
114 | @Override | 108 | @Override |
115 | public int compare(TaskConfiguration a, TaskConfiguration b) { | 109 | public int compare(TaskIdentifier a, TaskIdentifier b) { |
116 | return a.deadline.compareTo(b.deadline); | 110 | return a.deadline.compareTo(b.deadline); |
117 | } | 111 | } |
118 | }); | 112 | }); |
119 | 113 | ||
120 | |||
121 | /** | ||
122 | * Reset the scheduler forcefully. | ||
123 | * Intended to be used internally in the Scheduler, as well as in test teardown. | ||
124 | */ | ||
125 | public static void forceReset() { | ||
126 | scheduler_running = false; | ||
127 | readyCount = 0; | ||
128 | activeTask = null; | ||
129 | for (int i = 0; i < Priority.numberOfPriorities; ++i) { | ||
130 | readyLists[i] = new LinkedList<TaskConfiguration>(); | ||
131 | } | ||
132 | pending.clear(); | ||
133 | } | ||
134 | |||
135 | |||
136 | /** | 114 | /** |
137 | * Reasons for executing a task. | 115 | * Reasons for executing a task. |
138 | */ | 116 | */ |
@@ -147,94 +125,133 @@ public class Scheduler { | |||
147 | /** | 125 | /** |
148 | * The reason this task has been called by the scheduler. | 126 | * The reason this task has been called by the scheduler. |
149 | */ | 127 | */ |
150 | public Set<Reason> reasons = EnumSet.noneOf(Reason.class); | 128 | public EnumSet<Reason> reasons = EnumSet.noneOf(Reason.class); |
151 | } | 129 | } |
152 | 130 | ||
153 | /** | 131 | /** |
154 | * A task is the basic unit of work that is managed by the scheduler. | 132 | * Which operations is a task identifier interested in? |
155 | */ | 133 | */ |
156 | public static interface Task { | 134 | private static class TaskInterestOps { |
157 | public void run(RunContext ctx); | 135 | TaskIdentifier tid; |
136 | int interestOps; | ||
158 | } | 137 | } |
159 | 138 | ||
160 | /** | 139 | /** |
161 | * A TaskConfiguration represents a Task that will execute or has already been executed. | 140 | * Manage subscriptions for selection events on channels. |
162 | */ | 141 | */ |
163 | public static class TaskConfiguration implements Cancelable { | 142 | private static class Subscriptions { |
164 | private final Task task; | 143 | private static class ChannelInterest { |
165 | private RunContext ctx = new RunContext(); | 144 | SelectableChannel channel; |
166 | private boolean lifeness = true; | 145 | int interestOps; |
167 | private Priority priority; | ||
168 | private final AbsoluteTime deadline; | ||
169 | |||
170 | private ArrayList<SelectableChannel> eventChannels = null; | ||
171 | private ArrayList<Integer> eventTypes = null; | ||
172 | |||
173 | private boolean hasRun = false; | ||
174 | private boolean isCanceled = false; | ||
175 | |||
176 | /** | ||
177 | * Create a TaskIdentifier. | ||
178 | * | ||
179 | * @param delay when will the task be run? | ||
180 | * may be null to indicate that this task may not be run | ||
181 | * (but only queued directly) | ||
182 | * @param task task to run with this TaskIdentifier | ||
183 | */ | ||
184 | TaskConfiguration(RelativeTime delay, Task task) { | ||
185 | this.task = task; | ||
186 | if (delay == null) | ||
187 | this.deadline = null; | ||
188 | else | ||
189 | this.deadline = delay.toAbsolute(); | ||
190 | } | 146 | } |
191 | 147 | ||
192 | /** | 148 | List<ChannelInterest> channelInterests = Lists.newLinkedList(); |
193 | * Register the task configuration to run once the given event completed. | 149 | |
194 | * | 150 | void add(SelectableChannel channel, int interestOps) { |
195 | * @param channel channel that we wait for an event on | 151 | boolean found = false; |
196 | * @param eventType the event we wait on | 152 | for (ChannelInterest ci : channelInterests) { |
197 | */ | 153 | if (ci.channel == channel) { |
198 | private void addChannelEvent(SelectableChannel channel, int eventType) { | 154 | ci.interestOps |= interestOps; |
199 | if (channel == null) { | 155 | if ((ci.interestOps | SelectionKey.OP_CONNECT | SelectionKey.OP_READ) != 0) { |
200 | throw new AssertionError("channel must be non-null"); | 156 | throw new AssertionError("OP_CONNECT and OP_READ are incompatible in java"); |
157 | } | ||
158 | found = true; | ||
159 | break; | ||
160 | } | ||
201 | } | 161 | } |
202 | if (eventChannels == null) { | 162 | if (!found) { |
203 | eventChannels = new ArrayList<SelectableChannel>(); | 163 | ChannelInterest ci = new ChannelInterest(); |
204 | eventTypes = new ArrayList<Integer>(); | 164 | ci.channel = channel; |
165 | ci.interestOps = interestOps; | ||
166 | channelInterests.add(ci); | ||
205 | } | 167 | } |
206 | eventChannels.add(channel); | 168 | } |
207 | eventTypes.add(eventType); | ||
208 | 169 | ||
209 | int interestOp = eventToInterestOp[eventType]; | 170 | void apply(TaskIdentifier tid) { |
171 | for (ChannelInterest ci : channelInterests) { | ||
172 | SelectionKey key = ci.channel.keyFor(selector); | ||
173 | if (key == null || !key.isValid()) { | ||
174 | try { | ||
175 | key = ci.channel.register(selector, ci.interestOps); | ||
176 | key.attach(new LinkedList()); | ||
177 | } catch (ClosedChannelException e) { | ||
178 | throw new IOError(e); | ||
179 | } | ||
180 | } else { | ||
181 | key.interestOps(key.interestOps() | ci.interestOps); | ||
182 | } | ||
183 | @SuppressWarnings("unchecked") | ||
184 | LinkedList<TaskInterestOps> opl = (LinkedList<TaskInterestOps>) key.attachment(); | ||
185 | TaskInterestOps tio = new TaskInterestOps(); | ||
186 | tio.tid = tid; | ||
187 | tio.interestOps = ci.interestOps; | ||
188 | opl.add(tio); | ||
189 | } | ||
190 | } | ||
210 | 191 | ||
211 | SelectionKey key = channel.keyFor(selector); | 192 | void stop(TaskIdentifier tid) { |
212 | if (key == null || !key.isValid()) { | 193 | for (ChannelInterest ci : channelInterests) { |
213 | try { | 194 | SelectionKey key = ci.channel.keyFor(selector); |
214 | // tread safety ... avoid deadlock | 195 | if (key == null || !key.isValid()) { |
215 | selector.wakeup(); | 196 | logger.warn("missing selection key"); |
216 | key = channel.register(selector, interestOp, new TaskConfiguration[4]); | 197 | return; |
217 | } catch (ClosedChannelException e) { | ||
218 | throw new IOError(e); | ||
219 | } | 198 | } |
220 | } else { | 199 | @SuppressWarnings("unchecked") |
221 | if ((key.interestOps() & interestOp) != 0) { | 200 | LinkedList<TaskInterestOps> interestList = (LinkedList<TaskInterestOps>) key.attachment(); |
222 | throw new AssertionError("interest op registered twice"); | 201 | Iterator<TaskInterestOps> it = interestList.iterator(); |
202 | int remainingInterestOps = 0; | ||
203 | while (it.hasNext()) { | ||
204 | TaskInterestOps ops = it.next(); | ||
205 | if (ops.tid == tid) { | ||
206 | it.remove(); | ||
207 | } else { | ||
208 | remainingInterestOps |= ops.interestOps; | ||
209 | } | ||
223 | } | 210 | } |
224 | key.interestOps(key.interestOps() | interestOp); | 211 | key.interestOps(remainingInterestOps); |
225 | } | 212 | } |
213 | } | ||
214 | } | ||
226 | 215 | ||
227 | TaskConfiguration[] subscribers = (TaskConfiguration[]) key.attachment(); | 216 | /** |
228 | if (subscribers[eventType] != null) { | 217 | * A task is the basic unit of work that is managed by the scheduler. |
229 | throw new AssertionError("subscriber registered twice"); | 218 | */ |
230 | } | 219 | public static interface Task { |
231 | subscribers[eventType] = this; | 220 | public void run(RunContext ctx); |
221 | } | ||
232 | 222 | ||
233 | if (subscribers[EVENT_CONNECT] != null && subscribers[EVENT_READ] != null) { | 223 | /** |
234 | throw new AssertionError("OP_CONNECT and OP_READ are incompatible in java"); | 224 | * Representation of a task that has been scheduled, and can be canceled |
235 | } | 225 | * until the task has run. |
226 | */ | ||
227 | public static class TaskIdentifier implements Cancelable { | ||
228 | private boolean hasRun = false; | ||
229 | private boolean isCanceled = false; | ||
230 | private final Task task; | ||
231 | private final RunContext ctx = new RunContext(); | ||
232 | private final boolean lifeness; | ||
233 | private final Priority priority; | ||
234 | private final AbsoluteTime deadline; | ||
235 | private final Subscriptions subscriptions; | ||
236 | |||
237 | public TaskIdentifier(Task task, EnumSet<Reason> reasons) { | ||
238 | this.ctx.reasons = reasons; | ||
239 | this.task = task; | ||
240 | lifeness = true; | ||
241 | priority = Priority.DEFAULT; | ||
242 | deadline = null; | ||
243 | subscriptions = null; | ||
244 | } | ||
245 | |||
246 | public TaskIdentifier(TaskConfiguration tc) { | ||
247 | this.task = tc.task; | ||
248 | this.subscriptions = tc.subscriptions; | ||
249 | this.deadline = tc.deadline; | ||
250 | this.priority = tc.priority; | ||
251 | this.lifeness = tc.lifeness; | ||
236 | } | 252 | } |
237 | 253 | ||
254 | |||
238 | private void run() { | 255 | private void run() { |
239 | if (hasRun) { | 256 | if (hasRun) { |
240 | throw new AssertionError("same task ran twice"); | 257 | throw new AssertionError("same task ran twice"); |
@@ -242,14 +259,18 @@ public class Scheduler { | |||
242 | if (isCanceled) { | 259 | if (isCanceled) { |
243 | return; | 260 | return; |
244 | } | 261 | } |
245 | TaskConfiguration old = activeTask; | 262 | TaskIdentifier old = activeTask; |
246 | activeTask = this; | 263 | activeTask = this; |
247 | task.run(ctx); | 264 | task.run(ctx); |
248 | hasRun = true; | 265 | hasRun = true; |
249 | activeTask = old; | 266 | activeTask = old; |
250 | } | 267 | } |
251 | 268 | ||
269 | @Override | ||
252 | public void cancel() { | 270 | public void cancel() { |
271 | if (hasRun) { | ||
272 | throw new AssertionError("can't cancel task that already ran"); | ||
273 | } | ||
253 | if (isCanceled) { | 274 | if (isCanceled) { |
254 | throw new AssertionError("task canceled twice"); | 275 | throw new AssertionError("task canceled twice"); |
255 | } | 276 | } |
@@ -257,55 +278,59 @@ public class Scheduler { | |||
257 | pending.remove(this); | 278 | pending.remove(this); |
258 | } | 279 | } |
259 | 280 | ||
260 | public Cancelable schedule() { | 281 | public void deregister() { |
261 | lock.lock(); | 282 | if (subscriptions != null) { |
262 | if (this.deadline == null) | 283 | subscriptions.stop(this); |
263 | throw new AssertionError("a task without deadline may not be scheduled"); | ||
264 | if (priority == null) { | ||
265 | if (activeTask != null) { | ||
266 | priority = activeTask.priority; | ||
267 | } else { | ||
268 | priority = Priority.DEFAULT; | ||
269 | } | ||
270 | } | 284 | } |
271 | pending.add(this); | ||
272 | lock.unlock(); | ||
273 | return this; | ||
274 | } | 285 | } |
286 | } | ||
275 | 287 | ||
276 | private void deregister() { | 288 | /** |
277 | if (eventChannels == null) { | 289 | * A TaskConfiguration contains all information to schedule a task. |
278 | return; | 290 | */ |
279 | } | 291 | public static class TaskConfiguration { |
280 | lock.lock(); | 292 | private final Task task; |
281 | for (int i = 0; i < eventChannels.size(); ++i) { | 293 | private boolean lifeness = true; |
282 | SelectionKey key = eventChannels.get(i).keyFor(selector); | 294 | private Priority priority; |
283 | TaskConfiguration[] subscribers = (TaskConfiguration[]) key.attachment(); | 295 | private final AbsoluteTime deadline; |
284 | int interestOp = eventToInterestOp[eventTypes.get(i)]; | ||
285 | if (subscribers[eventTypes.get(i)] == null || (key.interestOps() | interestOp) == 0) { | ||
286 | throw new AssertionError("deregistering event that has not been registered"); | ||
287 | } | ||
288 | subscribers[eventTypes.get(i)] = null; | ||
289 | key.interestOps(key.interestOps() & (~interestOp)); | ||
290 | } | ||
291 | 296 | ||
292 | lock.unlock(); | 297 | private Subscriptions subscriptions; |
293 | } | ||
294 | 298 | ||
295 | public void selectRead(SelectableChannel channel) { | 299 | /** |
296 | addChannelEvent(channel, EVENT_READ); | 300 | * Create a TaskIdentifier. |
301 | * | ||
302 | * @param delay when will the task be run? | ||
303 | * may be null to indicate that this task may not be run | ||
304 | * (but only queued directly) | ||
305 | * @param task task to run with this TaskIdentifier | ||
306 | */ | ||
307 | TaskConfiguration(RelativeTime delay, Task task) { | ||
308 | if (delay == null) | ||
309 | throw new AssertionError("task delay may not be 'null'"); | ||
310 | this.task = task; | ||
311 | this.deadline = delay.toAbsolute(); | ||
297 | } | 312 | } |
298 | 313 | ||
299 | public void selectWrite(SelectableChannel channel) { | 314 | public TaskIdentifier schedule() { |
300 | addChannelEvent(channel, EVENT_WRITE); | ||
301 | } | ||
302 | 315 | ||
303 | public void selectConnect(SelectableChannel channel) { | 316 | if (priority == null) { |
304 | addChannelEvent(channel, EVENT_CONNECT); | 317 | if (activeTask != null) { |
318 | priority = activeTask.priority; | ||
319 | } else { | ||
320 | priority = Priority.DEFAULT; | ||
321 | } | ||
322 | } | ||
323 | TaskIdentifier tid = new TaskIdentifier(this); | ||
324 | if (subscriptions != null) | ||
325 | subscriptions.apply(tid); | ||
326 | pending.add(tid); | ||
327 | return tid; | ||
305 | } | 328 | } |
306 | 329 | ||
307 | public void selectAccept(SelectableChannel channel) { | 330 | public void addSelectEvent(SelectableChannel channel, int event) { |
308 | addChannelEvent(channel, EVENT_ACCEPT); | 331 | if (subscriptions == null) |
332 | subscriptions = new Subscriptions(); | ||
333 | subscriptions.add(channel, event); | ||
309 | } | 334 | } |
310 | } | 335 | } |
311 | 336 | ||
@@ -314,14 +339,7 @@ public class Scheduler { | |||
314 | * the same priority. | 339 | * the same priority. |
315 | */ | 340 | */ |
316 | public static void addContinuation(Task task, EnumSet<Reason> reasons) { | 341 | public static void addContinuation(Task task, EnumSet<Reason> reasons) { |
317 | lock.lock(); | 342 | queueReady(new TaskIdentifier(task, reasons)); |
318 | TaskConfiguration t = new TaskConfiguration(null, task); | ||
319 | t.ctx.reasons = reasons; | ||
320 | t.priority = Priority.DEFAULT; | ||
321 | queueReady(t); | ||
322 | logger.debug("about to wake up"); | ||
323 | lock.unlock(); | ||
324 | selector.wakeup(); | ||
325 | } | 343 | } |
326 | 344 | ||
327 | /** | 345 | /** |
@@ -343,26 +361,41 @@ public class Scheduler { | |||
343 | * @param task the task to run after delay | 361 | * @param task the task to run after delay |
344 | * @return the TaskIdentifier, can be used to cancel the task until it has been executed. | 362 | * @return the TaskIdentifier, can be used to cancel the task until it has been executed. |
345 | */ | 363 | */ |
346 | public static TaskConfiguration addDelayed(RelativeTime delay, Task task) { | 364 | public static TaskIdentifier addDelayed(RelativeTime delay, Task task) { |
347 | TaskConfiguration tid = new TaskConfiguration(delay, task); | 365 | TaskConfiguration tid = new TaskConfiguration(delay, task); |
348 | tid.schedule(); | 366 | return tid.schedule(); |
349 | return tid; | ||
350 | } | 367 | } |
351 | 368 | ||
352 | public static TaskConfiguration addRead(RelativeTime timeout, | 369 | /** |
353 | SelectableChannel chan, Task task) { | 370 | * Add a task to run after the specified delay, or after the given channel |
371 | * is ready to read, whichever occurs first. | ||
372 | * | ||
373 | * @param timeout time to wait until running the task | ||
374 | * @param chan chennel of interest | ||
375 | * @param task task to run | ||
376 | * @return task identifier | ||
377 | */ | ||
378 | public static TaskIdentifier addRead(RelativeTime timeout, | ||
379 | SelectableChannel chan, Task task) { | ||
354 | TaskConfiguration tid = new TaskConfiguration(timeout, task); | 380 | TaskConfiguration tid = new TaskConfiguration(timeout, task); |
355 | tid.addChannelEvent(chan, EVENT_READ); | 381 | tid.addSelectEvent(chan, SelectionKey.OP_READ); |
356 | tid.schedule(); | 382 | return tid.schedule(); |
357 | return tid; | ||
358 | } | 383 | } |
359 | 384 | ||
360 | public static TaskConfiguration addWrite(RelativeTime timeout, | 385 | /** |
361 | SelectableChannel chan, Task task) { | 386 | * Add a task to run after the specified delay, or after the given channel |
387 | * is ready to write, whichever occurs first. | ||
388 | * | ||
389 | * @param timeout to wait until running the task | ||
390 | * @param chan channel of interest | ||
391 | * @param task task to run | ||
392 | * @return task identifier | ||
393 | */ | ||
394 | public static TaskIdentifier addWrite(RelativeTime timeout, | ||
395 | SelectableChannel chan, Task task) { | ||
362 | TaskConfiguration tid = new TaskConfiguration(timeout, task); | 396 | TaskConfiguration tid = new TaskConfiguration(timeout, task); |
363 | tid.addChannelEvent(chan, EVENT_WRITE); | 397 | tid.addSelectEvent(chan, SelectionKey.OP_WRITE); |
364 | tid.schedule(); | 398 | return tid.schedule(); |
365 | return tid; | ||
366 | } | 399 | } |
367 | 400 | ||
368 | /** | 401 | /** |
@@ -372,14 +405,11 @@ public class Scheduler { | |||
372 | * @return true to continue the main loop, false to exit | 405 | * @return true to continue the main loop, false to exit |
373 | */ | 406 | */ |
374 | private static boolean checkLiveness() { | 407 | private static boolean checkLiveness() { |
375 | lock.lock(); | ||
376 | if (readyCount > 0) { | 408 | if (readyCount > 0) { |
377 | lock.unlock(); | ||
378 | return true; | 409 | return true; |
379 | } | 410 | } |
380 | for (TaskConfiguration t : pending) { | 411 | for (TaskIdentifier t : pending) { |
381 | if (t.lifeness) { | 412 | if (t.lifeness) { |
382 | lock.unlock(); | ||
383 | return true; | 413 | return true; |
384 | } | 414 | } |
385 | } | 415 | } |
@@ -387,30 +417,23 @@ public class Scheduler { | |||
387 | if (!pending.isEmpty()) { | 417 | if (!pending.isEmpty()) { |
388 | logger.debug("tasks pending but not alive -- disconnect"); | 418 | logger.debug("tasks pending but not alive -- disconnect"); |
389 | shutdown(); | 419 | shutdown(); |
390 | lock.unlock(); | ||
391 | return true; | 420 | return true; |
392 | } | 421 | } |
393 | |||
394 | lock.unlock(); | ||
395 | return false; | 422 | return false; |
396 | } | 423 | } |
397 | 424 | ||
398 | |||
399 | /** | 425 | /** |
400 | * Queue a Task for execution. | 426 | * Queue a Task for execution. |
401 | * | 427 | * |
402 | * @param tid TaskIdentifier of the ready task | 428 | * @param tid TaskIdentifier of the ready task |
403 | */ | 429 | */ |
404 | private static void queueReady(TaskConfiguration tid) { | 430 | private static void queueReady(TaskIdentifier tid) { |
405 | lock.lock(); | ||
406 | int idx = tid.priority.ordinal(); | 431 | int idx = tid.priority.ordinal(); |
407 | readyLists[idx].add(tid); | 432 | readyLists[idx].add(tid); |
408 | readyCount++; | 433 | readyCount++; |
409 | pending.remove(tid); | 434 | pending.remove(tid); |
410 | lock.unlock(); | ||
411 | } | 435 | } |
412 | 436 | ||
413 | |||
414 | /** | 437 | /** |
415 | * Queue all tasks with expired timeout. | 438 | * Queue all tasks with expired timeout. |
416 | * | 439 | * |
@@ -418,11 +441,10 @@ public class Scheduler { | |||
418 | */ | 441 | */ |
419 | private static RelativeTime handleTimeouts() { | 442 | private static RelativeTime handleTimeouts() { |
420 | RelativeTime timeout = RelativeTime.FOREVER; | 443 | RelativeTime timeout = RelativeTime.FOREVER; |
421 | lock.lock(); | ||
422 | 444 | ||
423 | // check if any timeouts occurred | 445 | // check if any timeouts occurred |
424 | while (true) { | 446 | while (true) { |
425 | TaskConfiguration t = pending.peek(); | 447 | TaskIdentifier t = pending.peek(); |
426 | if (t == null) { | 448 | if (t == null) { |
427 | break; | 449 | break; |
428 | } | 450 | } |
@@ -436,25 +458,19 @@ public class Scheduler { | |||
436 | break; | 458 | break; |
437 | } | 459 | } |
438 | } | 460 | } |
439 | lock.unlock(); | ||
440 | return timeout; | 461 | return timeout; |
441 | } | 462 | } |
442 | 463 | ||
443 | /** | 464 | |
444 | * If there is a subscribing task for the given event type, add it to the set of executable tasks. | 465 | private static void addReasonsFromInterestOp(EnumSet<Reason> reasons, int interestOps) { |
445 | * | 466 | if ((interestOps & SelectionKey.OP_READ) != 0) |
446 | * @param executableTasks set of executable tasks | 467 | reasons.add(Reason.READ_READY); |
447 | * @param subscribers subscriber set, one subscriber for each event type | 468 | if ((interestOps & SelectionKey.OP_WRITE) != 0) |
448 | * @param eventType event type we are interested in | 469 | reasons.add(Reason.WRITE_READY); |
449 | */ | 470 | if ((interestOps & SelectionKey.OP_CONNECT) != 0) |
450 | private static void addSubscriberTask(Collection<TaskConfiguration> executableTasks, | 471 | reasons.add(Reason.CONNECT_READY); |
451 | TaskConfiguration[] subscribers, int eventType) { | 472 | if ((interestOps & SelectionKey.OP_ACCEPT) != 0) |
452 | TaskConfiguration tc = subscribers[eventType]; | 473 | reasons.add(Reason.ACCEPT_READY); |
453 | if (tc == null) { | ||
454 | return; | ||
455 | } | ||
456 | executableTasks.add(tc); | ||
457 | tc.ctx.reasons.add(eventToReason[eventType]); | ||
458 | } | 474 | } |
459 | 475 | ||
460 | /** | 476 | /** |
@@ -463,10 +479,8 @@ public class Scheduler { | |||
463 | * @param timeout timeout for select | 479 | * @param timeout timeout for select |
464 | */ | 480 | */ |
465 | private static void handleSelect(RelativeTime timeout) { | 481 | private static void handleSelect(RelativeTime timeout) { |
466 | if (!lock.isHeldByCurrentThread()) | 482 | // gnunet-java uses microseconds, but the select api uses milliseconds |
467 | throw new AssertionError(); | ||
468 | long timeout_ms = timeout.getMicroseconds() / 1000; | 483 | long timeout_ms = timeout.getMicroseconds() / 1000; |
469 | lock.unlock(); | ||
470 | try { | 484 | try { |
471 | // selector.select(0) would block indefinitely (counter-intuitive, java's fault) | 485 | // selector.select(0) would block indefinitely (counter-intuitive, java's fault) |
472 | if (timeout_ms == 0) { | 486 | if (timeout_ms == 0) { |
@@ -480,39 +494,29 @@ public class Scheduler { | |||
480 | } | 494 | } |
481 | } catch (IOException e) { | 495 | } catch (IOException e) { |
482 | throw new IOError(e); | 496 | throw new IOError(e); |
483 | } finally { | ||
484 | lock.lock(); | ||
485 | } | 497 | } |
486 | 498 | ||
487 | logger.debug("select over"); | 499 | logger.debug("select over"); |
488 | 500 | ||
489 | // we use a set so that we don't execute any task twice | 501 | // we use a set so that we don't execute any task twice |
490 | Collection<TaskConfiguration> executableTasks = new HashSet<TaskConfiguration>(); | 502 | Collection<TaskIdentifier> executableTasks = new HashSet<TaskIdentifier>(); |
491 | for (SelectionKey sk : selector.selectedKeys()) { | 503 | for (SelectionKey sk : selector.selectedKeys()) { |
492 | TaskConfiguration[] subscribers = (TaskConfiguration[]) sk.attachment(); | 504 | @SuppressWarnings("unchecked") |
493 | 505 | LinkedList<TaskInterestOps> subscribers = (LinkedList<TaskInterestOps>) sk.attachment(); | |
494 | if (sk.isReadable()) { | 506 | for (TaskInterestOps ops : subscribers) { |
495 | addSubscriberTask(executableTasks, subscribers, EVENT_READ); | 507 | if ((sk.readyOps() & ops.interestOps) != 0) { |
496 | } | 508 | executableTasks.add(ops.tid); |
497 | if (sk.isWritable()) { | 509 | addReasonsFromInterestOp(ops.tid.ctx.reasons, sk.readyOps() & ops.interestOps); |
498 | addSubscriberTask(executableTasks, subscribers, EVENT_WRITE); | 510 | } |
499 | } | ||
500 | if (sk.isAcceptable()) { | ||
501 | addSubscriberTask(executableTasks, subscribers, EVENT_ACCEPT); | ||
502 | } | ||
503 | if (sk.isConnectable()) { | ||
504 | addSubscriberTask(executableTasks, subscribers, EVENT_CONNECT); | ||
505 | } | 511 | } |
506 | |||
507 | } | 512 | } |
508 | for (TaskConfiguration tt : executableTasks) { | 513 | for (TaskIdentifier tt : executableTasks) { |
509 | // cancel subscriptions to other events, we can execute now! | 514 | // cancel subscriptions to other events, we can execute now! |
510 | tt.deregister(); | 515 | tt.deregister(); |
511 | queueReady(tt); | 516 | queueReady(tt); |
512 | } | 517 | } |
513 | } | 518 | } |
514 | 519 | ||
515 | |||
516 | /** | 520 | /** |
517 | * Initialize and run scheduler. This function will return when all tasks | 521 | * Initialize and run scheduler. This function will return when all tasks |
518 | * have completed. | 522 | * have completed. |
@@ -529,10 +533,10 @@ public class Scheduler { | |||
529 | */ | 533 | */ |
530 | public static void run(Task initialTask) { | 534 | public static void run(Task initialTask) { |
531 | logger.debug("running scheduler"); | 535 | logger.debug("running scheduler"); |
532 | if (scheduler_running) { | 536 | if (schedulerRunning) { |
533 | throw new AssertionError("Scheduler already running"); | 537 | throw new AssertionError("Scheduler already running"); |
534 | } | 538 | } |
535 | scheduler_running = true; | 539 | schedulerRunning = true; |
536 | try { | 540 | try { |
537 | run_unchecked(initialTask); | 541 | run_unchecked(initialTask); |
538 | } finally { | 542 | } finally { |
@@ -543,7 +547,6 @@ public class Scheduler { | |||
543 | } | 547 | } |
544 | } | 548 | } |
545 | 549 | ||
546 | |||
547 | /** | 550 | /** |
548 | * Initialize and run scheduler. This function will return when all tasks | 551 | * Initialize and run scheduler. This function will return when all tasks |
549 | * have completed. Don't check if the scheduler is already running or not. | 552 | * have completed. Don't check if the scheduler is already running or not. |
@@ -556,12 +559,7 @@ public class Scheduler { | |||
556 | } | 559 | } |
557 | 560 | ||
558 | // the gnunet main loop | 561 | // the gnunet main loop |
559 | while (true) { | 562 | while (checkLiveness()) { |
560 | lock.lock(); | ||
561 | if (checkLiveness() == false) { | ||
562 | lock.unlock(); | ||
563 | break; | ||
564 | } | ||
565 | RelativeTime nextTimeout = handleTimeouts(); | 563 | RelativeTime nextTimeout = handleTimeouts(); |
566 | if (nextTimeout.getMicroseconds() < 0) { | 564 | if (nextTimeout.getMicroseconds() < 0) { |
567 | logger.warn("negative timeout for select"); | 565 | logger.warn("negative timeout for select"); |
@@ -569,7 +567,6 @@ public class Scheduler { | |||
569 | 567 | ||
570 | // don't select if there are no tasks; we are done! | 568 | // don't select if there are no tasks; we are done! |
571 | if (readyCount == 0 && pending.isEmpty()) { | 569 | if (readyCount == 0 && pending.isEmpty()) { |
572 | lock.unlock(); | ||
573 | return; | 570 | return; |
574 | } | 571 | } |
575 | 572 | ||
@@ -580,7 +577,6 @@ public class Scheduler { | |||
580 | handleSelect(nextTimeout); | 577 | handleSelect(nextTimeout); |
581 | } | 578 | } |
582 | runReady(); | 579 | runReady(); |
583 | lock.unlock(); | ||
584 | } | 580 | } |
585 | 581 | ||
586 | if (readyCount != 0) { | 582 | if (readyCount != 0) { |
@@ -618,9 +614,9 @@ public class Scheduler { | |||
618 | // start executing from the highest priority down to 0 | 614 | // start executing from the highest priority down to 0 |
619 | for (int p = Priority.numberOfPriorities - 1; p >= 0; p--) { | 615 | for (int p = Priority.numberOfPriorities - 1; p >= 0; p--) { |
620 | // execute all tasks with priority p | 616 | // execute all tasks with priority p |
621 | LinkedList<TaskConfiguration> queue = readyLists[p]; | 617 | LinkedList<TaskIdentifier> queue = readyLists[p]; |
622 | while (!queue.isEmpty()) { | 618 | while (!queue.isEmpty()) { |
623 | TaskConfiguration tid = queue.removeFirst(); | 619 | TaskIdentifier tid = queue.removeFirst(); |
624 | readyCount--; | 620 | readyCount--; |
625 | tid.run(); | 621 | tid.run(); |
626 | } | 622 | } |
@@ -637,13 +633,27 @@ public class Scheduler { | |||
637 | */ | 633 | */ |
638 | public static void shutdown() { | 634 | public static void shutdown() { |
639 | // queueReady() while iterating would yield concurrent modification exn otherwise | 635 | // queueReady() while iterating would yield concurrent modification exn otherwise |
640 | for (TaskConfiguration tid : new ArrayList<TaskConfiguration>(pending)) { | 636 | for (TaskIdentifier tid : new ArrayList<TaskIdentifier>(pending)) { |
641 | tid.ctx.reasons.add(Reason.SHUTDOWN); | 637 | tid.ctx.reasons.add(Reason.SHUTDOWN); |
642 | queueReady(tid); | 638 | queueReady(tid); |
643 | } | 639 | } |
644 | pending.clear(); | 640 | pending.clear(); |
645 | } | 641 | } |
646 | 642 | ||
643 | /** | ||
644 | * Reset the scheduler forcefully. | ||
645 | * Intended to be used internally in the Scheduler, as well as in test teardown. | ||
646 | */ | ||
647 | public static void forceReset() { | ||
648 | schedulerRunning = false; | ||
649 | readyCount = 0; | ||
650 | activeTask = null; | ||
651 | for (int i = 0; i < Priority.numberOfPriorities; ++i) { | ||
652 | readyLists[i] = Lists.newLinkedList(); | ||
653 | } | ||
654 | pending.clear(); | ||
655 | } | ||
656 | |||
647 | 657 | ||
648 | /** | 658 | /** |
649 | * A handle to a file system object that can be selected on. | 659 | * A handle to a file system object that can be selected on. |
diff --git a/src/main/java/org/gnunet/util/Server.java b/src/main/java/org/gnunet/util/Server.java index 8a86b45..7f816d0 100644 --- a/src/main/java/org/gnunet/util/Server.java +++ b/src/main/java/org/gnunet/util/Server.java | |||
@@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; | |||
27 | 27 | ||
28 | import java.io.IOException; | 28 | import java.io.IOException; |
29 | import java.net.SocketAddress; | 29 | import java.net.SocketAddress; |
30 | import java.nio.channels.SelectionKey; | ||
30 | import java.nio.channels.ServerSocketChannel; | 31 | import java.nio.channels.ServerSocketChannel; |
31 | import java.nio.channels.SocketChannel; | 32 | import java.nio.channels.SocketChannel; |
32 | import java.util.ArrayList; | 33 | import java.util.ArrayList; |
@@ -403,7 +404,7 @@ public class Server { | |||
403 | addAcceptSocket(sock); | 404 | addAcceptSocket(sock); |
404 | } | 405 | } |
405 | }); | 406 | }); |
406 | b.selectAccept(sock); | 407 | b.addSelectEvent(sock, SelectionKey.OP_ACCEPT); |
407 | acceptTask = b.schedule(); | 408 | acceptTask = b.schedule(); |
408 | } | 409 | } |
409 | 410 | ||
diff --git a/src/main/java/org/gnunet/util/Service.java b/src/main/java/org/gnunet/util/Service.java index d93e296..a150089 100644 --- a/src/main/java/org/gnunet/util/Service.java +++ b/src/main/java/org/gnunet/util/Service.java | |||
@@ -30,6 +30,7 @@ import java.net.InetSocketAddress; | |||
30 | import java.net.SocketAddress; | 30 | import java.net.SocketAddress; |
31 | import java.nio.ByteBuffer; | 31 | import java.nio.ByteBuffer; |
32 | import java.nio.channels.Pipe; | 32 | import java.nio.channels.Pipe; |
33 | import java.nio.channels.SelectionKey; | ||
33 | import java.util.LinkedList; | 34 | import java.util.LinkedList; |
34 | 35 | ||
35 | /** | 36 | /** |
@@ -107,7 +108,7 @@ public abstract class Service extends Program { | |||
107 | 108 | ||
108 | Scheduler.TaskConfiguration t = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, | 109 | Scheduler.TaskConfiguration t = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, |
109 | new SigpipeTask()); | 110 | new SigpipeTask()); |
110 | t.selectRead(p.getSource()); | 111 | t.addSelectEvent(p.getSource(), SelectionKey.OP_READ); |
111 | sigpipeTask = t.schedule(); | 112 | sigpipeTask = t.schedule(); |
112 | sigpipeChannel = p.getSource(); | 113 | sigpipeChannel = p.getSource(); |
113 | } | 114 | } |
diff --git a/src/main/java/org/gnunet/voting/Ballot.java b/src/main/java/org/gnunet/voting/Ballot.java index 49f1465..0d8de27 100644 --- a/src/main/java/org/gnunet/voting/Ballot.java +++ b/src/main/java/org/gnunet/voting/Ballot.java | |||
@@ -24,7 +24,7 @@ import com.google.common.base.Joiner; | |||
24 | import com.google.common.base.Optional; | 24 | import com.google.common.base.Optional; |
25 | import com.google.common.collect.BiMap; | 25 | import com.google.common.collect.BiMap; |
26 | import com.google.common.collect.HashBiMap; | 26 | import com.google.common.collect.HashBiMap; |
27 | import com.google.common.collect.Maps; | 27 | import com.google.common.primitives.Longs; |
28 | import org.gnunet.util.*; | 28 | import org.gnunet.util.*; |
29 | 29 | ||
30 | import java.security.MessageDigest; | 30 | import java.security.MessageDigest; |
@@ -38,18 +38,22 @@ import java.util.regex.Pattern; | |||
38 | public class Ballot { | 38 | public class Ballot { |
39 | 39 | ||
40 | String topic; | 40 | String topic; |
41 | String group; | ||
41 | List<String> choices; | 42 | List<String> choices; |
42 | AbsoluteTime electionStartTime; | 43 | AbsoluteTime startTime; |
43 | AbsoluteTime electionEndTime; | 44 | AbsoluteTime closingTime; |
45 | AbsoluteTime queryTime; | ||
46 | AbsoluteTime endTime; | ||
44 | BiMap<String,PeerIdentity> authorities; | 47 | BiMap<String,PeerIdentity> authorities; |
45 | SortedMap<String,CryptoECC.Signature> registrationSigs; | 48 | SortedMap<String,CryptoECC.Signature> registrationSigs; |
46 | CryptoECC.PublicKey caPub; | 49 | CryptoECC.PublicSignKey caPub; |
47 | CryptoECC.PublicKey issuerPub; | 50 | CryptoECC.PublicSignKey issuerPub; |
48 | CryptoECC.Signature issuerSig; | 51 | CryptoECC.Signature issuerSig; |
49 | CryptoECC.PublicKey voter_pub; | 52 | CryptoECC.PublicSignKey voterPub; |
53 | CryptoECC.Signature voterGroupCert; | ||
50 | CryptoECC.Signature permission; | 54 | CryptoECC.Signature permission; |
51 | CryptoECC.PublicKey voter_sig; | 55 | CryptoECC.PublicSignKey voterSig; |
52 | SortedMap<String,CryptoECC.Signature> vouchers; | 56 | SortedMap<String,CryptoECC.Signature> voucherSigs; |
53 | 57 | ||
54 | /** | 58 | /** |
55 | * Choice in plaintext. | 59 | * Choice in plaintext. |
@@ -60,8 +64,8 @@ public class Ballot { | |||
60 | /** | 64 | /** |
61 | * Load a ballot from file. | 65 | * Load a ballot from file. |
62 | * | 66 | * |
67 | * @param filename name of file to load ballot from | ||
63 | * @throws InvalidBallotException | 68 | * @throws InvalidBallotException |
64 | * @param filename | ||
65 | */ | 69 | */ |
66 | public Ballot(String filename) { | 70 | public Ballot(String filename) { |
67 | Configuration cfg = new Configuration(); | 71 | Configuration cfg = new Configuration(); |
@@ -69,10 +73,49 @@ public class Ballot { | |||
69 | fillBallot(cfg); | 73 | fillBallot(cfg); |
70 | } | 74 | } |
71 | 75 | ||
76 | /** | ||
77 | * Load a ballot from a configuration. | ||
78 | * | ||
79 | * @param cfg configuration to load ballot from | ||
80 | * @throws InvalidBallotException | ||
81 | */ | ||
72 | public Ballot(Configuration cfg) { | 82 | public Ballot(Configuration cfg) { |
73 | fillBallot(cfg); | 83 | fillBallot(cfg); |
74 | } | 84 | } |
75 | 85 | ||
86 | /** | ||
87 | * Parse the specified time value from the ballot, | ||
88 | * converting a human-readable time value to human time when no | ||
89 | * timestamp is given. | ||
90 | * @param cfg configuration to read the value from | ||
91 | * @param timeValueName name suffix of the time option | ||
92 | * @return the time value | ||
93 | */ | ||
94 | private AbsoluteTime getTime(Configuration cfg, String timeValueName) { | ||
95 | Optional<String> optTimeHuman = cfg.getValueString("election", "TIME_" + timeValueName); | ||
96 | Optional<String> optTimeStamp = cfg.getValueString("election", "TIMESTAMP_" + timeValueName); | ||
97 | if (optTimeStamp.isPresent()) { | ||
98 | try { | ||
99 | long stamp = Long.parseLong(optTimeStamp.get()); | ||
100 | return AbsoluteTime.fromSeconds(stamp); | ||
101 | } catch (NumberFormatException e) { | ||
102 | throw new InvalidBallotException("time value " + timeValueName + " malformed"); | ||
103 | } | ||
104 | } else if (optTimeHuman.isPresent()) { | ||
105 | AbsoluteTime time = AbsoluteTime.fromString(optTimeHuman.get()); | ||
106 | if (null == time) { | ||
107 | throw new InvalidBallotException("timestamp value " + timeValueName + " malformed"); | ||
108 | } | ||
109 | return time; | ||
110 | } | ||
111 | throw new InvalidBallotException("time value " + timeValueName + " missing"); | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Fill the ballot with information from the given configuration. | ||
116 | * | ||
117 | * @param cfg configuration to read from | ||
118 | */ | ||
76 | private void fillBallot(Configuration cfg) { | 119 | private void fillBallot(Configuration cfg) { |
77 | Optional<String> optTopic = cfg.getValueString("election", "TOPIC"); | 120 | Optional<String> optTopic = cfg.getValueString("election", "TOPIC"); |
78 | if (!optTopic.isPresent()) { | 121 | if (!optTopic.isPresent()) { |
@@ -87,6 +130,11 @@ public class Ballot { | |||
87 | if (choices.size() < 2) { | 130 | if (choices.size() < 2) { |
88 | throw new InvalidBallotException("less than two choices present"); | 131 | throw new InvalidBallotException("less than two choices present"); |
89 | } | 132 | } |
133 | Optional<String> optGroup = cfg.getValueString("election", "GROUP"); | ||
134 | if (!optGroup.isPresent()) { | ||
135 | throw new InvalidBallotException("ballot must have elegibility group"); | ||
136 | } | ||
137 | group = optGroup.get(); | ||
90 | authorities = HashBiMap.create(); | 138 | authorities = HashBiMap.create(); |
91 | for (Map.Entry<String,String> e : cfg.getSection("authorities").entrySet()) { | 139 | for (Map.Entry<String,String> e : cfg.getSection("authorities").entrySet()) { |
92 | String alias = e.getKey(); | 140 | String alias = e.getKey(); |
@@ -104,13 +152,13 @@ public class Ballot { | |||
104 | if (!optCaPub.isPresent()) { | 152 | if (!optCaPub.isPresent()) { |
105 | throw new InvalidBallotException("no CA pub key given"); | 153 | throw new InvalidBallotException("no CA pub key given"); |
106 | } | 154 | } |
107 | caPub = CryptoECC.PublicKey.fromString(optCaPub.get()); | 155 | caPub = CryptoECC.PublicSignKey.fromString(optCaPub.get()); |
108 | if (null == caPub) { | 156 | if (null == caPub) { |
109 | throw new InvalidBallotException("CA pub key invalid"); | 157 | throw new InvalidBallotException("CA pub key invalid"); |
110 | } | 158 | } |
111 | Optional<String> optIssuerPub = cfg.getValueString("election", "ISSUER_PUB"); | 159 | Optional<String> optIssuerPub = cfg.getValueString("election", "ISSUER_PUB"); |
112 | if (optIssuerPub.isPresent()) { | 160 | if (optIssuerPub.isPresent()) { |
113 | issuerPub = CryptoECC.PublicKey.fromString(optIssuerPub.get()); | 161 | issuerPub = CryptoECC.PublicSignKey.fromString(optIssuerPub.get()); |
114 | Optional<String> optIssuerSig = cfg.getValueString("election", "ISSUER_SIG"); | 162 | Optional<String> optIssuerSig = cfg.getValueString("election", "ISSUER_SIG"); |
115 | if (!optIssuerSig.isPresent()) { | 163 | if (!optIssuerSig.isPresent()) { |
116 | throw new InvalidBallotException("issuer public key present, but no signature"); | 164 | throw new InvalidBallotException("issuer public key present, but no signature"); |
@@ -128,6 +176,17 @@ public class Ballot { | |||
128 | } | 176 | } |
129 | registrationSigs.put(e.getKey(), sig); | 177 | registrationSigs.put(e.getKey(), sig); |
130 | } | 178 | } |
179 | voucherSigs = new TreeMap<String, CryptoECC.Signature>(); | ||
180 | for (Map.Entry<String,String> e : cfg.getSection("vouchers").entrySet()) { | ||
181 | CryptoECC.Signature sig = CryptoECC.Signature.fromString(e.getValue()); | ||
182 | if (null == sig) { | ||
183 | throw new InvalidBallotException("voucher signature has invalid format"); | ||
184 | } | ||
185 | if (!authorities.containsKey(e.getKey())) { | ||
186 | throw new InvalidBallotException("ballot contains superfluous voucher signature"); | ||
187 | } | ||
188 | voucherSigs.put(e.getKey(), sig); | ||
189 | } | ||
131 | Optional<String> optChoiceId = cfg.getValueString("vote", "CHOICE_ID"); | 190 | Optional<String> optChoiceId = cfg.getValueString("vote", "CHOICE_ID"); |
132 | if (optChoiceId.isPresent()) { | 191 | if (optChoiceId.isPresent()) { |
133 | choiceId = Integer.parseInt(optChoiceId.get()); | 192 | choiceId = Integer.parseInt(optChoiceId.get()); |
@@ -137,11 +196,27 @@ public class Ballot { | |||
137 | } else { | 196 | } else { |
138 | choiceId = -1; | 197 | choiceId = -1; |
139 | } | 198 | } |
199 | |||
200 | Optional<String> optVoterPub = cfg.getValueString("vote", "VOTER_PUB"); | ||
201 | if (optVoterPub.isPresent()) { | ||
202 | voterPub = CryptoECC.PublicSignKey.fromString(optVoterPub.get()); | ||
203 | } | ||
204 | |||
205 | startTime = getTime(cfg, "START"); | ||
206 | closingTime = getTime(cfg, "CLOSING"); | ||
207 | queryTime = getTime(cfg, "QUERY"); | ||
208 | endTime = getTime(cfg, "END"); | ||
140 | } | 209 | } |
141 | 210 | ||
211 | /** | ||
212 | * Get a hash code that uniquely defines the election information of | ||
213 | * the ballot. | ||
214 | * | ||
215 | * @return GUID of this ballot | ||
216 | */ | ||
142 | public HashCode getBallotGuid() { | 217 | public HashCode getBallotGuid() { |
143 | if (issuerSig == null) { | 218 | if (issuerPub == null) { |
144 | throw new InvalidBallotException("can't compute GUID of non-issued ballot"); | 219 | throw new InvalidBallotException("can't compute GUID of a ballot without issuer"); |
145 | } | 220 | } |
146 | MessageDigest digest; | 221 | MessageDigest digest; |
147 | try { | 222 | try { |
@@ -150,8 +225,6 @@ public class Ballot { | |||
150 | throw new RuntimeException("crypto algorithm required but not provided"); | 225 | throw new RuntimeException("crypto algorithm required but not provided"); |
151 | } | 226 | } |
152 | digest.update(topic.getBytes()); | 227 | digest.update(topic.getBytes()); |
153 | //digest.update(Longs.toByteArray(electionStartTime.getSeconds())); | ||
154 | //digest.update(Longs.toByteArray(electionEndTime.getSeconds())); | ||
155 | for (String choice : choices) { | 228 | for (String choice : choices) { |
156 | digest.update(choice.getBytes()); | 229 | digest.update(choice.getBytes()); |
157 | } | 230 | } |
@@ -163,11 +236,16 @@ public class Ballot { | |||
163 | digest.update(issuerPub.y); | 236 | digest.update(issuerPub.y); |
164 | digest.update(caPub.x); | 237 | digest.update(caPub.x); |
165 | digest.update(caPub.y); | 238 | digest.update(caPub.y); |
239 | digest.update(Longs.toByteArray(startTime.getSeconds())); | ||
240 | digest.update(Longs.toByteArray(endTime.getSeconds())); | ||
241 | digest.update(Longs.toByteArray(closingTime.getSeconds())); | ||
242 | digest.update(Longs.toByteArray(queryTime.getSeconds())); | ||
166 | return new HashCode(digest.digest()); | 243 | return new HashCode(digest.digest()); |
167 | } | 244 | } |
168 | 245 | ||
169 | /** | 246 | /** |
170 | * Encode the given choice permanently in the ballot. | 247 | * Encode the given choice permanently in the ballot. |
248 | * Also encodes the voter's public key. | ||
171 | * | 249 | * |
172 | * @param choice the choice to encode the ballot | 250 | * @param choice the choice to encode the ballot |
173 | * @param privateKey the private key to use for encoding | 251 | * @param privateKey the private key to use for encoding |
@@ -181,21 +259,39 @@ public class Ballot { | |||
181 | } | 259 | } |
182 | i++; | 260 | i++; |
183 | } | 261 | } |
262 | voterPub = CryptoECC.computePublicKey(privateKey); | ||
184 | if (choiceId == -1) { | 263 | if (choiceId == -1) { |
185 | throw new InvalidBallotException(String.format("choice '%s' not valid", choice)); | 264 | throw new InvalidBallotException(String.format("choice '%s' not valid", choice)); |
186 | } | 265 | } |
187 | } | 266 | } |
188 | 267 | ||
268 | /** | ||
269 | * Write the current state of the ballot to a configuration. | ||
270 | * | ||
271 | * @return a configuration with the state of this ballot | ||
272 | */ | ||
189 | public Configuration toConfiguration() { | 273 | public Configuration toConfiguration() { |
190 | Configuration cfg = new Configuration(); | 274 | Configuration cfg = new Configuration(); |
191 | cfg.setValueString("election", "TOPIC", topic); | 275 | cfg.setValueString("election", "TOPIC", topic); |
276 | cfg.setValueString("election", "GROUP", group); | ||
192 | cfg.setValueString("election", "CHOICES", Joiner.on("//").join(choices)); | 277 | cfg.setValueString("election", "CHOICES", Joiner.on("//").join(choices)); |
193 | cfg.setValueString("election", "CA_PUB", caPub.toString()); | 278 | cfg.setValueString("election", "CA_PUB", caPub.toString()); |
279 | cfg.setValueNumber("election", "TIMESTAMP_START", startTime.getSeconds()); | ||
280 | cfg.setValueNumber("election", "TIMESTAMP_CLOSING", startTime.getSeconds()); | ||
281 | cfg.setValueNumber("election", "TIMESTAMP_QUERY", startTime.getSeconds()); | ||
282 | cfg.setValueNumber("election", "TIMESTAMP_END", startTime.getSeconds()); | ||
194 | for (Map.Entry<String, PeerIdentity> e : authorities.entrySet()) { | 283 | for (Map.Entry<String, PeerIdentity> e : authorities.entrySet()) { |
195 | cfg.setValueString("authorities", e.getKey(), e.getValue().toString()); | 284 | cfg.setValueString("authorities", e.getKey(), e.getValue().toString()); |
196 | } | 285 | } |
197 | for (Map.Entry<String, CryptoECC.Signature> e : registrationSigs.entrySet()) { | 286 | if (null != registrationSigs) { |
198 | cfg.setValueString("registration-signatures", e.getKey(), e.getValue().toString()); | 287 | for (Map.Entry<String, CryptoECC.Signature> e : registrationSigs.entrySet()) { |
288 | cfg.setValueString("registration-signatures", e.getKey(), e.getValue().toString()); | ||
289 | } | ||
290 | } | ||
291 | if (null != voucherSigs) { | ||
292 | for (Map.Entry<String, CryptoECC.Signature> e : voucherSigs.entrySet()) { | ||
293 | cfg.setValueString("vouchers", e.getKey(), e.getValue().toString()); | ||
294 | } | ||
199 | } | 295 | } |
200 | if (null != issuerPub) { | 296 | if (null != issuerPub) { |
201 | cfg.setValueString("election", "ISSUER_PUB", issuerPub.toString()); | 297 | cfg.setValueString("election", "ISSUER_PUB", issuerPub.toString()); |
@@ -204,19 +300,52 @@ public class Ballot { | |||
204 | if (-1 != choiceId) { | 300 | if (-1 != choiceId) { |
205 | cfg.setValueNumber("vote", "CHOICE_ID", choiceId); | 301 | cfg.setValueNumber("vote", "CHOICE_ID", choiceId); |
206 | } | 302 | } |
303 | if (null != voterPub) { | ||
304 | cfg.setValueString("vote", "VOTER_PUB", voterPub.toString()); | ||
305 | } | ||
207 | return cfg; | 306 | return cfg; |
208 | } | 307 | } |
209 | 308 | ||
309 | /** | ||
310 | * Serialize the ballot to a string | ||
311 | * | ||
312 | * @return the serialized ballot | ||
313 | */ | ||
210 | public String serialize() { | 314 | public String serialize() { |
211 | return toConfiguration().serialize(); | 315 | return toConfiguration().serialize(); |
212 | } | 316 | } |
213 | 317 | ||
318 | |||
319 | /** | ||
320 | * Get a human readable description of the ballot's current state. | ||
321 | * | ||
322 | * @return the ballot description | ||
323 | */ | ||
214 | public String describe() { | 324 | public String describe() { |
215 | StringBuilder buf = new StringBuilder(); | 325 | StringBuilder buf = new StringBuilder(); |
326 | |||
216 | buf.append("Topic: "); | 327 | buf.append("Topic: "); |
217 | buf.append("'"); | 328 | buf.append("'"); |
218 | buf.append(topic); | 329 | buf.append(topic); |
219 | buf.append("'\n"); | 330 | buf.append("'\n"); |
331 | |||
332 | buf.append("Voter Group: "); | ||
333 | buf.append(group); | ||
334 | buf.append("\n"); | ||
335 | |||
336 | buf.append("Start Time: "); | ||
337 | buf.append(startTime.toFancyString()); | ||
338 | buf.append("\n"); | ||
339 | buf.append("Closing Time: "); | ||
340 | buf.append(closingTime.toFancyString()); | ||
341 | buf.append("\n"); | ||
342 | buf.append("Query Time: "); | ||
343 | buf.append(queryTime.toFancyString()); | ||
344 | buf.append("\n"); | ||
345 | buf.append("End Time: "); | ||
346 | buf.append(endTime.toFancyString()); | ||
347 | buf.append("\n"); | ||
348 | |||
220 | buf.append("Choices:\n"); | 349 | buf.append("Choices:\n"); |
221 | for (int i = 0; i < choices.size(); i++) { | 350 | for (int i = 0; i < choices.size(); i++) { |
222 | buf.append(""+(i+1)); | 351 | buf.append(""+(i+1)); |
@@ -247,6 +376,14 @@ public class Ballot { | |||
247 | } | 376 | } |
248 | buf.append("\n"); | 377 | buf.append("\n"); |
249 | } | 378 | } |
379 | if (!voucherSigs.isEmpty()) { | ||
380 | buf.append("ballot's vote has been submitted to with the following authorities:\n"); | ||
381 | for (Map.Entry<String, CryptoECC.Signature> e : voucherSigs.entrySet()) { | ||
382 | buf.append(e.getKey()); | ||
383 | buf.append(" "); | ||
384 | } | ||
385 | buf.append("\n"); | ||
386 | } | ||
250 | else { | 387 | else { |
251 | buf.append("ballot not registered\n"); | 388 | buf.append("ballot not registered\n"); |
252 | } | 389 | } |
@@ -258,12 +395,27 @@ public class Ballot { | |||
258 | return buf.toString(); | 395 | return buf.toString(); |
259 | } | 396 | } |
260 | 397 | ||
398 | |||
399 | /** | ||
400 | * Get the list of authorities that did not yet receive the ballot's vote. | ||
401 | * | ||
402 | * @return list of unsubmitted-to authorities | ||
403 | */ | ||
261 | public List<PeerIdentity> getRemainingSubmitAuthorities() { | 404 | public List<PeerIdentity> getRemainingSubmitAuthorities() { |
262 | // FIXME: only return remaining authorities | 405 | LinkedList<PeerIdentity> remaining = new LinkedList<PeerIdentity>(); |
263 | return new ArrayList<PeerIdentity>(authorities.values()); | 406 | for (SortedMap.Entry<String,PeerIdentity> x : authorities.entrySet()) { |
407 | if (!voucherSigs.containsKey(x.getKey())) | ||
408 | remaining.add(x.getValue()); | ||
409 | } | ||
410 | return remaining; | ||
264 | } | 411 | } |
265 | 412 | ||
266 | 413 | /** | |
414 | * Get a list of authorities that did not receive the registration for this | ||
415 | * ballot yet. | ||
416 | * | ||
417 | * @return list of authorities that don't know about this ballot | ||
418 | */ | ||
267 | public List<PeerIdentity> getRemainingRegisterAuthorities() { | 419 | public List<PeerIdentity> getRemainingRegisterAuthorities() { |
268 | LinkedList<PeerIdentity> remaining = new LinkedList<PeerIdentity>(); | 420 | LinkedList<PeerIdentity> remaining = new LinkedList<PeerIdentity>(); |
269 | for (SortedMap.Entry<String,PeerIdentity> x : authorities.entrySet()) { | 421 | for (SortedMap.Entry<String,PeerIdentity> x : authorities.entrySet()) { |
@@ -273,16 +425,44 @@ public class Ballot { | |||
273 | return remaining; | 425 | return remaining; |
274 | } | 426 | } |
275 | 427 | ||
428 | /** | ||
429 | * Add the issuer to the ballot, and sign the election information in the ballot. | ||
430 | * | ||
431 | * @param privateKey private key of the issuer | ||
432 | */ | ||
276 | public void issue(CryptoECC.PrivateKey privateKey) { | 433 | public void issue(CryptoECC.PrivateKey privateKey) { |
277 | issuerPub = CryptoECC.computePublicKey(privateKey); | 434 | issuerPub = CryptoECC.computePublicKey(privateKey); |
278 | issuerSig = CryptoECC.sign(getBallotGuid().data, privateKey, issuerPub); | 435 | issuerSig = CryptoECC.sign(getBallotGuid().data, privateKey, issuerPub); |
279 | } | 436 | } |
280 | 437 | ||
438 | /** | ||
439 | * Add an authorities registration signature to the list of known registrations. | ||
440 | * | ||
441 | * @param currentAuthority authority we registered with | ||
442 | * @param registrationSignature signature over this ballot's GUID from the authority | ||
443 | */ | ||
281 | public void addRegistrationSignature(PeerIdentity currentAuthority, CryptoECC.Signature registrationSignature) { | 444 | public void addRegistrationSignature(PeerIdentity currentAuthority, CryptoECC.Signature registrationSignature) { |
282 | String alias = authorities.inverse().get(currentAuthority); | 445 | String alias = authorities.inverse().get(currentAuthority); |
283 | registrationSigs.put(alias, registrationSignature); | 446 | registrationSigs.put(alias, registrationSignature); |
284 | } | 447 | } |
285 | 448 | ||
449 | /** | ||
450 | * Add a voucher, that is, a signature about the fact that an authority received a vote, | ||
451 | * to the list of vouchers | ||
452 | * | ||
453 | * @param currentAuthority authority that received the vote | ||
454 | * @param voucherSignature signature from the authority | ||
455 | */ | ||
456 | public void addVoucher(PeerIdentity currentAuthority, CryptoECC.Signature voucherSignature) { | ||
457 | String alias = authorities.inverse().get(currentAuthority); | ||
458 | voucherSigs.put(alias, voucherSignature); | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * Get a list of all authorities. | ||
463 | * | ||
464 | * @return list of all authorities | ||
465 | */ | ||
286 | public List<PeerIdentity> getAuthorities() { | 466 | public List<PeerIdentity> getAuthorities() { |
287 | return new ArrayList<PeerIdentity>(authorities.values()); | 467 | return new ArrayList<PeerIdentity>(authorities.values()); |
288 | } | 468 | } |
diff --git a/src/main/java/org/gnunet/voting/BallotTool.java b/src/main/java/org/gnunet/voting/BallotTool.java index 619afa5..1abf8fd 100644 --- a/src/main/java/org/gnunet/voting/BallotTool.java +++ b/src/main/java/org/gnunet/voting/BallotTool.java | |||
@@ -25,26 +25,15 @@ import com.google.common.base.Charsets; | |||
25 | import com.google.common.io.ByteStreams; | 25 | import com.google.common.io.ByteStreams; |
26 | import com.google.common.io.Files; | 26 | 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; | ||
29 | import org.gnunet.mesh.MeshRunabout; | ||
30 | import org.gnunet.mesh.TunnelEndHandler; | ||
31 | import org.gnunet.util.Configuration; | ||
32 | import org.gnunet.util.CryptoECC; | 28 | import org.gnunet.util.CryptoECC; |
33 | import org.gnunet.util.PeerIdentity; | ||
34 | import org.gnunet.util.Program; | 29 | import org.gnunet.util.Program; |
35 | import org.gnunet.util.getopt.Argument; | 30 | import org.gnunet.util.getopt.Argument; |
36 | import org.gnunet.util.getopt.ArgumentAction; | 31 | import org.gnunet.util.getopt.ArgumentAction; |
37 | import org.gnunet.voting.messages.BallotRegisterRequestMessage; | ||
38 | import org.gnunet.voting.messages.SubmitMessage; | ||
39 | import org.gnunet.voting.messages.SubmitResponseMessage; | ||
40 | 32 | ||
41 | import java.io.File; | 33 | import java.io.File; |
42 | import java.io.FileOutputStream; | 34 | import java.io.FileOutputStream; |
43 | import java.io.IOException; | 35 | import java.io.IOException; |
44 | import java.io.InputStream; | 36 | import java.io.InputStream; |
45 | import java.nio.charset.Charset; | ||
46 | import java.util.List; | ||
47 | import java.util.regex.Pattern; | ||
48 | 37 | ||
49 | /** | 38 | /** |
50 | * Tool for creating, manipulating and submitting ballot files. | 39 | * Tool for creating, manipulating and submitting ballot files. |
@@ -89,11 +78,11 @@ public class BallotTool { | |||
89 | String select = null; | 78 | String select = null; |
90 | 79 | ||
91 | @Argument( | 80 | @Argument( |
92 | shortname = "p", | 81 | shortname = "G", |
93 | longname = "permission", | 82 | longname = "certify-group", |
94 | action = ArgumentAction.SET, | 83 | action = ArgumentAction.SET, |
95 | description = "request permission to vote from the certificate authority") | 84 | description = "request a certificate that the voter belongs to the ballot's group") |
96 | boolean permission = false; | 85 | boolean certifyGroup = false; |
97 | 86 | ||
98 | @Argument( | 87 | @Argument( |
99 | shortname = "V", | 88 | shortname = "V", |
@@ -226,7 +215,7 @@ public class BallotTool { | |||
226 | System.err.println("key invalid"); | 215 | System.err.println("key invalid"); |
227 | return; | 216 | return; |
228 | } | 217 | } |
229 | CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey); | 218 | CryptoECC.PublicSignKey publicKey = CryptoECC.computePublicKey(privateKey); |
230 | System.out.println(publicKey.toString()); | 219 | System.out.println(publicKey.toString()); |
231 | } | 220 | } |
232 | 221 | ||
@@ -302,12 +291,12 @@ public class BallotTool { | |||
302 | c.run(); | 291 | c.run(); |
303 | return; | 292 | return; |
304 | } | 293 | } |
305 | if (permission) { | 294 | if (certifyGroup) { |
306 | if (this.unprocessedArgs.length != 2) { | 295 | if (this.unprocessedArgs.length != 2) { |
307 | System.err.println("-p/--permission requires exactly two positional arguments"); | 296 | System.err.println("-G/--certify-group requires exactly two positional arguments"); |
308 | return; | 297 | return; |
309 | } | 298 | } |
310 | PermissionCommand c = new PermissionCommand(getConfiguration(), | 299 | CertifyGroupCommand c = new CertifyGroupCommand(getConfiguration(), |
311 | unprocessedArgs[0], unprocessedArgs[1]); | 300 | unprocessedArgs[0], unprocessedArgs[1]); |
312 | c.run(); | 301 | c.run(); |
313 | return; | 302 | return; |
diff --git a/src/main/java/org/gnunet/voting/CertificateAuthorityDaemon.java b/src/main/java/org/gnunet/voting/CertificateAuthorityDaemon.java new file mode 100644 index 0000000..fc54bbf --- /dev/null +++ b/src/main/java/org/gnunet/voting/CertificateAuthorityDaemon.java | |||
@@ -0,0 +1,70 @@ | |||
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 | import com.google.common.collect.Maps; | ||
23 | import org.gnunet.mesh.Mesh; | ||
24 | import org.gnunet.mesh.MeshRunabout; | ||
25 | import org.gnunet.testbed.CompressedConfig; | ||
26 | import org.gnunet.util.*; | ||
27 | import org.gnunet.voting.messages.*; | ||
28 | import org.slf4j.Logger; | ||
29 | import org.slf4j.LoggerFactory; | ||
30 | |||
31 | import java.util.HashMap; | ||
32 | import java.util.HashSet; | ||
33 | import java.util.Set; | ||
34 | |||
35 | /** | ||
36 | * Gives a voter a certificate that acknowledges that he belongs to a certain group | ||
37 | * (e.g. all people from bavaria over 18 years old) | ||
38 | */ | ||
39 | public class CertificateAuthorityDaemon extends Program { | ||
40 | private static final Logger logger = LoggerFactory | ||
41 | .getLogger(CertificateAuthorityDaemon.class); | ||
42 | |||
43 | public static final int MESH_PORT = 1002; | ||
44 | private Mesh mesh; | ||
45 | |||
46 | public class CaMeshReceiver extends MeshRunabout { | ||
47 | public void visit(CertificateRequestMessage m) { | ||
48 | logger.info("granting group cert for '" + m.group + "'"); | ||
49 | CertificateGrantMessage gm = new CertificateGrantMessage(); | ||
50 | gm.expiration = AbsoluteTime.FOREVER.asMessage(); | ||
51 | gm.groupCertificate = CryptoECC.Signature.randomSignature(); | ||
52 | getSender().receiveDone(); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | public CertificateAuthorityDaemon(String[] args) { | ||
57 | super(args); | ||
58 | } | ||
59 | |||
60 | public static void main(String[] args) { | ||
61 | CertificateAuthorityDaemon daemon = new CertificateAuthorityDaemon(args); | ||
62 | daemon.start(); | ||
63 | } | ||
64 | |||
65 | @Override | ||
66 | public void run() { | ||
67 | logger.info("running ca daemon"); | ||
68 | mesh = new Mesh(getConfiguration(), null, null, new CaMeshReceiver(), MESH_PORT); | ||
69 | } | ||
70 | } | ||
diff --git a/src/main/java/org/gnunet/voting/CertificateAuthorityService.java b/src/main/java/org/gnunet/voting/CertificateAuthorityService.java deleted file mode 100644 index 23aa1f2..0000000 --- a/src/main/java/org/gnunet/voting/CertificateAuthorityService.java +++ /dev/null | |||
@@ -1,55 +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 | import org.gnunet.mesh.Mesh; | ||
23 | import org.gnunet.mesh.MeshRunabout; | ||
24 | import org.gnunet.util.RelativeTime; | ||
25 | import org.gnunet.util.Service; | ||
26 | import org.gnunet.voting.messages.CertificateRequestMessage; | ||
27 | |||
28 | /** | ||
29 | * Permits or denies a voter to participate in an election. | ||
30 | */ | ||
31 | public class CertificateAuthorityService extends Service { | ||
32 | public static final int MESH_PORT = 1001; | ||
33 | private Mesh mesh; | ||
34 | |||
35 | |||
36 | private class CaMeshReceiver extends MeshRunabout { | ||
37 | public void visit(CertificateRequestMessage m) { | ||
38 | // TODO: just sign the | ||
39 | } | ||
40 | } | ||
41 | |||
42 | public CertificateAuthorityService(String[] args) { | ||
43 | super("voting-ca", RelativeTime.FOREVER, true, args); | ||
44 | } | ||
45 | |||
46 | public static void main(String[] args) { | ||
47 | CertificateAuthorityService service = new CertificateAuthorityService(args); | ||
48 | service.start(); | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | public void run() { | ||
53 | mesh = new Mesh(getConfiguration(), null, null, new CaMeshReceiver(), MESH_PORT); | ||
54 | } | ||
55 | } | ||
diff --git a/src/main/java/org/gnunet/voting/PermissionCommand.java b/src/main/java/org/gnunet/voting/CertifyGroupCommand.java index 7e73dbd..e76ba1f 100644 --- a/src/main/java/org/gnunet/voting/PermissionCommand.java +++ b/src/main/java/org/gnunet/voting/CertifyGroupCommand.java | |||
@@ -65,17 +65,17 @@ import org.gnunet.mesh.Mesh; | |||
65 | import org.gnunet.mesh.MeshRunabout; | 65 | import org.gnunet.mesh.MeshRunabout; |
66 | import org.gnunet.mesh.TunnelEndHandler; | 66 | import org.gnunet.mesh.TunnelEndHandler; |
67 | import org.gnunet.util.Configuration; | 67 | import org.gnunet.util.Configuration; |
68 | import org.gnunet.util.PeerIdentity; | 68 | import org.gnunet.util.CryptoECC; |
69 | import org.gnunet.voting.messages.CertificateGrantMessage; | ||
70 | import org.gnunet.voting.messages.CertificateRequestMessage; | ||
69 | import org.gnunet.voting.messages.QueryFailureMessage; | 71 | import org.gnunet.voting.messages.QueryFailureMessage; |
70 | import org.gnunet.voting.messages.QueryMessage; | ||
71 | import org.gnunet.voting.messages.QueryResponseMessage; | ||
72 | 72 | ||
73 | import java.io.File; | 73 | import java.io.File; |
74 | import java.util.List; | ||
75 | import java.util.Random; | 74 | import java.util.Random; |
76 | 75 | ||
77 | public class PermissionCommand extends MeshRunabout implements TunnelEndHandler { | 76 | public class CertifyGroupCommand extends MeshRunabout implements TunnelEndHandler { |
78 | private final String ballotFilename; | 77 | private final String ballotFilename; |
78 | private final String pubKeyString; | ||
79 | private Ballot ballot; | 79 | private Ballot ballot; |
80 | private final Configuration cfg; | 80 | private final Configuration cfg; |
81 | private Mesh mesh; | 81 | private Mesh mesh; |
@@ -88,16 +88,9 @@ public class PermissionCommand extends MeshRunabout implements TunnelEndHandler | |||
88 | throw new AssertionError(); | 88 | throw new AssertionError(); |
89 | } | 89 | } |
90 | 90 | ||
91 | public void visit(QueryResponseMessage m) { | 91 | public void visit(CertificateGrantMessage m) { |
92 | submitted = true; | 92 | submitted = true; |
93 | if (m.results.length != ballot.choices.size()) { | 93 | System.out.println("certificate granted"); |
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 | 94 | ||
102 | tunnel.destroy(); | 95 | tunnel.destroy(); |
103 | mesh.destroy(); | 96 | mesh.destroy(); |
@@ -111,9 +104,10 @@ public class PermissionCommand extends MeshRunabout implements TunnelEndHandler | |||
111 | mesh.destroy(); | 104 | mesh.destroy(); |
112 | } | 105 | } |
113 | 106 | ||
114 | public PermissionCommand(Configuration cfg, String ballotFilename, String pubKeyString) { | 107 | public CertifyGroupCommand(Configuration cfg, String ballotFilename, String pubKeyString) { |
115 | this.cfg = cfg; | 108 | this.cfg = cfg; |
116 | this.ballotFilename = ballotFilename; | 109 | this.ballotFilename = ballotFilename; |
110 | this.pubKeyString = pubKeyString; | ||
117 | } | 111 | } |
118 | 112 | ||
119 | public void run() { | 113 | public void run() { |
@@ -126,7 +120,10 @@ public class PermissionCommand extends MeshRunabout implements TunnelEndHandler | |||
126 | 120 | ||
127 | Random r = new Random(); | 121 | Random r = new Random(); |
128 | mesh = new Mesh(cfg, this, this); | 122 | mesh = new Mesh(cfg, this, this); |
129 | tunnel = mesh.createTunnel(null /* FIXME */, CertificateAuthorityService.MESH_PORT, true, true, null); | 123 | tunnel = mesh.createTunnel(null /* FIXME */, CertificateAuthorityDaemon.MESH_PORT, true, true, null); |
130 | //tunnel.send(m); | 124 | CertificateRequestMessage m = new CertificateRequestMessage(); |
125 | m.group = ballot.group; | ||
126 | m.publicKey = CryptoECC.PublicSignKey.fromString(pubKeyString); | ||
127 | tunnel.send(m); | ||
131 | } | 128 | } |
132 | } | 129 | } |
diff --git a/src/main/java/org/gnunet/voting/RegisterCommand.java b/src/main/java/org/gnunet/voting/RegisterCommand.java index f9d4c4d..1878c48 100644 --- a/src/main/java/org/gnunet/voting/RegisterCommand.java +++ b/src/main/java/org/gnunet/voting/RegisterCommand.java | |||
@@ -49,16 +49,18 @@ import org.gnunet.mesh.TunnelEndHandler; | |||
49 | import org.gnunet.testbed.CompressedConfig; | 49 | import org.gnunet.testbed.CompressedConfig; |
50 | import org.gnunet.util.Configuration; | 50 | import org.gnunet.util.Configuration; |
51 | import org.gnunet.util.PeerIdentity; | 51 | import org.gnunet.util.PeerIdentity; |
52 | import org.gnunet.voting.messages.BallotRegisterFailureMessage; | ||
52 | import org.gnunet.voting.messages.BallotRegisterRequestMessage; | 53 | import org.gnunet.voting.messages.BallotRegisterRequestMessage; |
53 | import org.gnunet.voting.messages.BallotRegisterRespondMessage; | 54 | import org.gnunet.voting.messages.BallotRegisterSuccessMessage; |
54 | import org.gnunet.voting.messages.SubmitMessage; | ||
55 | import org.gnunet.voting.messages.SubmitResponseMessage; | ||
56 | 55 | ||
57 | import java.io.File; | 56 | import java.io.File; |
58 | import java.io.IOException; | 57 | import java.io.IOException; |
59 | import java.util.List; | 58 | import java.util.List; |
60 | import java.util.Random; | 59 | import java.util.Random; |
61 | 60 | ||
61 | /** | ||
62 | * Command for registering a ballot with an authority. | ||
63 | */ | ||
62 | public class RegisterCommand extends MeshRunabout implements TunnelEndHandler { | 64 | public class RegisterCommand extends MeshRunabout implements TunnelEndHandler { |
63 | private final String ballotFilename; | 65 | private final String ballotFilename; |
64 | private Ballot ballot; | 66 | private Ballot ballot; |
@@ -74,9 +76,9 @@ public class RegisterCommand extends MeshRunabout implements TunnelEndHandler { | |||
74 | throw new AssertionError(); | 76 | throw new AssertionError(); |
75 | } | 77 | } |
76 | 78 | ||
77 | public void visit(BallotRegisterRespondMessage m) { | 79 | public void visit(BallotRegisterSuccessMessage m) { |
78 | submitted = true; | 80 | submitted = true; |
79 | System.out.println("vote successfully registered"); | 81 | System.out.println("ballot successfully registered"); |
80 | ballot.addRegistrationSignature(currentAuthority, m.registrationSignature); | 82 | ballot.addRegistrationSignature(currentAuthority, m.registrationSignature); |
81 | try { | 83 | try { |
82 | Files.write(ballot.serialize(), new File(ballotFilename), Charsets.UTF_8); | 84 | Files.write(ballot.serialize(), new File(ballotFilename), Charsets.UTF_8); |
@@ -88,6 +90,14 @@ public class RegisterCommand extends MeshRunabout implements TunnelEndHandler { | |||
88 | mesh.destroy(); | 90 | mesh.destroy(); |
89 | } | 91 | } |
90 | 92 | ||
93 | |||
94 | public void visit(BallotRegisterFailureMessage m) { | ||
95 | submitted = true; | ||
96 | System.out.println("registering failed: " + m.reason); | ||
97 | tunnel.destroy(); | ||
98 | mesh.destroy(); | ||
99 | } | ||
100 | |||
91 | public RegisterCommand(Configuration cfg, String ballotFilename) { | 101 | public RegisterCommand(Configuration cfg, String ballotFilename) { |
92 | this.cfg = cfg; | 102 | this.cfg = cfg; |
93 | this.ballotFilename = ballotFilename; | 103 | this.ballotFilename = ballotFilename; |
diff --git a/src/main/java/org/gnunet/voting/SubmitCommand.java b/src/main/java/org/gnunet/voting/SubmitCommand.java index d00ea69..43e10c9 100644 --- a/src/main/java/org/gnunet/voting/SubmitCommand.java +++ b/src/main/java/org/gnunet/voting/SubmitCommand.java | |||
@@ -21,18 +21,27 @@ | |||
21 | package org.gnunet.voting; | 21 | package org.gnunet.voting; |
22 | 22 | ||
23 | 23 | ||
24 | import com.google.common.base.Charsets; | ||
25 | import com.google.common.io.Files; | ||
24 | import org.gnunet.mesh.Mesh; | 26 | import org.gnunet.mesh.Mesh; |
25 | import org.gnunet.mesh.MeshRunabout; | 27 | import org.gnunet.mesh.MeshRunabout; |
26 | import org.gnunet.mesh.TunnelEndHandler; | 28 | import org.gnunet.mesh.TunnelEndHandler; |
29 | import org.gnunet.util.AbsoluteTime; | ||
27 | import org.gnunet.util.Configuration; | 30 | import org.gnunet.util.Configuration; |
31 | import org.gnunet.util.CryptoECC; | ||
28 | import org.gnunet.util.PeerIdentity; | 32 | import org.gnunet.util.PeerIdentity; |
33 | import org.gnunet.voting.messages.SubmitFailureMessage; | ||
29 | import org.gnunet.voting.messages.SubmitMessage; | 34 | import org.gnunet.voting.messages.SubmitMessage; |
30 | import org.gnunet.voting.messages.SubmitResponseMessage; | 35 | import org.gnunet.voting.messages.SubmitSuccessMessage; |
31 | 36 | ||
32 | import java.io.File; | 37 | import java.io.File; |
38 | import java.io.IOException; | ||
33 | import java.util.List; | 39 | import java.util.List; |
34 | import java.util.Random; | 40 | import java.util.Random; |
35 | 41 | ||
42 | /** | ||
43 | * Command that submits a ballot with a vote to a remaining authority. | ||
44 | */ | ||
36 | public class SubmitCommand extends MeshRunabout implements TunnelEndHandler { | 45 | public class SubmitCommand extends MeshRunabout implements TunnelEndHandler { |
37 | private final String ballotFilename; | 46 | private final String ballotFilename; |
38 | private Ballot ballot; | 47 | private Ballot ballot; |
@@ -40,6 +49,7 @@ public class SubmitCommand extends MeshRunabout implements TunnelEndHandler { | |||
40 | private Mesh mesh; | 49 | private Mesh mesh; |
41 | private Mesh.Tunnel<Void> tunnel; | 50 | private Mesh.Tunnel<Void> tunnel; |
42 | private boolean submitted = false; | 51 | private boolean submitted = false; |
52 | private PeerIdentity currentAuthority; | ||
43 | 53 | ||
44 | @Override | 54 | @Override |
45 | public void onTunnelEnd(Mesh.Tunnel tunnel) { | 55 | public void onTunnelEnd(Mesh.Tunnel tunnel) { |
@@ -47,9 +57,23 @@ public class SubmitCommand extends MeshRunabout implements TunnelEndHandler { | |||
47 | throw new AssertionError(); | 57 | throw new AssertionError(); |
48 | } | 58 | } |
49 | 59 | ||
50 | public void visit(SubmitResponseMessage m) { | 60 | public void visit(SubmitSuccessMessage m) { |
51 | submitted = true; | 61 | submitted = true; |
52 | System.out.println("vote successfully submitted"); | 62 | System.out.println("vote successfully submitted"); |
63 | ballot.addVoucher(currentAuthority, m.voucherSig); | ||
64 | try { | ||
65 | Files.write(ballot.serialize(), new File(ballotFilename), Charsets.UTF_8); | ||
66 | } catch (IOException e) { | ||
67 | System.out.println("could not write ballot file"); | ||
68 | return; | ||
69 | } | ||
70 | tunnel.destroy(); | ||
71 | mesh.destroy(); | ||
72 | } | ||
73 | |||
74 | public void visit(SubmitFailureMessage m) { | ||
75 | submitted = true; | ||
76 | System.out.println("vote not submitted: " + m.reason); | ||
53 | tunnel.destroy(); | 77 | tunnel.destroy(); |
54 | mesh.destroy(); | 78 | mesh.destroy(); |
55 | } | 79 | } |
@@ -74,9 +98,17 @@ public class SubmitCommand extends MeshRunabout implements TunnelEndHandler { | |||
74 | Random r = new Random(); | 98 | Random r = new Random(); |
75 | PeerIdentity authority = remainingAuthorities.get(r.nextInt(remainingAuthorities.size())); | 99 | PeerIdentity authority = remainingAuthorities.get(r.nextInt(remainingAuthorities.size())); |
76 | System.out.println("submitting to authority" + authority.toString()); | 100 | System.out.println("submitting to authority" + authority.toString()); |
101 | currentAuthority = authority; | ||
77 | mesh = new Mesh(cfg, null, this); | 102 | mesh = new Mesh(cfg, null, this); |
78 | tunnel = mesh.createTunnel(authority, TallyAuthorityDaemon.MESH_PORT, true, true, null); | 103 | tunnel = mesh.createTunnel(authority, TallyAuthorityDaemon.MESH_PORT, true, true, null); |
79 | SubmitMessage m = new SubmitMessage(); | 104 | SubmitMessage m = new SubmitMessage(); |
105 | if (ballot.voterPub == null) { | ||
106 | throw new InvalidBallotException("no voter in ballot"); | ||
107 | } | ||
108 | m.voterPub = ballot.voterPub; | ||
109 | // FIXME: implement certs | ||
110 | m.groupCertExpiration = AbsoluteTime.FOREVER.asMessage(); | ||
111 | m.groupCert = CryptoECC.Signature.randomSignature(); | ||
80 | m.ballotGuid = ballot.getBallotGuid(); | 112 | m.ballotGuid = ballot.getBallotGuid(); |
81 | m.choiceId = ballot.choiceId; | 113 | m.choiceId = ballot.choiceId; |
82 | tunnel.send(m); | 114 | tunnel.send(m); |
diff --git a/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java b/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java index a74d175..aa27f9c 100644 --- a/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java +++ b/src/main/java/org/gnunet/voting/TallyAuthorityDaemon.java | |||
@@ -31,6 +31,10 @@ import org.slf4j.LoggerFactory; | |||
31 | 31 | ||
32 | import java.util.*; | 32 | import java.util.*; |
33 | 33 | ||
34 | |||
35 | /** | ||
36 | * Daemon that is responsible for counting votes. | ||
37 | */ | ||
34 | public class TallyAuthorityDaemon extends Program { | 38 | public class TallyAuthorityDaemon extends Program { |
35 | private static final Logger logger = LoggerFactory | 39 | private static final Logger logger = LoggerFactory |
36 | .getLogger(TallyAuthorityDaemon.class); | 40 | .getLogger(TallyAuthorityDaemon.class); |
@@ -38,14 +42,23 @@ public class TallyAuthorityDaemon extends Program { | |||
38 | public static final int MESH_PORT = 1002; | 42 | public static final int MESH_PORT = 1002; |
39 | private Mesh mesh; | 43 | private Mesh mesh; |
40 | 44 | ||
45 | /** | ||
46 | * All elections known to this authority | ||
47 | */ | ||
41 | private HashMap<HashCode, ElectionState> elections = Maps.newHashMap(); | 48 | private HashMap<HashCode, ElectionState> elections = Maps.newHashMap(); |
42 | 49 | ||
50 | /** | ||
51 | * State of one election. | ||
52 | */ | ||
43 | class ElectionState { | 53 | class ElectionState { |
54 | /** | ||
55 | * The ballot that describes this election. | ||
56 | */ | ||
44 | Ballot ballot; | 57 | Ballot ballot; |
45 | /** | 58 | /** |
46 | * Set of voters that have submitted their ballot. | 59 | * Set of voters that have submitted their ballot. |
47 | */ | 60 | */ |
48 | Set<CryptoECC.PublicKey> voters = new HashSet<CryptoECC.PublicKey>(); | 61 | Set<CryptoECC.PublicSignKey> voters = new HashSet<CryptoECC.PublicSignKey>(); |
49 | 62 | ||
50 | /** | 63 | /** |
51 | * Maping from choice to number of votes for that choice. | 64 | * Maping from choice to number of votes for that choice. |
@@ -53,47 +66,92 @@ public class TallyAuthorityDaemon extends Program { | |||
53 | int[] tally; | 66 | int[] tally; |
54 | } | 67 | } |
55 | 68 | ||
56 | |||
57 | private class TallyMeshReceiver extends MeshRunabout { | 69 | private class TallyMeshReceiver extends MeshRunabout { |
58 | public void visit(SubmitMessage m) { | 70 | public void visit(SubmitMessage m) { |
71 | logger.debug("got submit message"); | ||
59 | ElectionState electionState = elections.get(m.ballotGuid); | 72 | ElectionState electionState = elections.get(m.ballotGuid); |
60 | if (null == electionState) { | 73 | if (null == electionState) { |
61 | return; | 74 | SubmitFailureMessage fm = new SubmitFailureMessage(); |
75 | fm.reason = "no matching ballot found"; | ||
76 | getSender().send(fm); | ||
77 | } else if (m.choiceId < 0 || m.choiceId >= electionState.tally.length) { | ||
78 | SubmitFailureMessage fm = new SubmitFailureMessage(); | ||
79 | fm.reason = "invalid vote"; | ||
80 | getSender().send(fm); | ||
81 | } else if (electionState.voters.contains(m.voterPub)) { | ||
82 | SubmitFailureMessage fm = new SubmitFailureMessage(); | ||
83 | fm.reason = "duplicate vote detected"; | ||
84 | getSender().send(fm); | ||
85 | } else if (!electionState.ballot.startTime.isDue()) { | ||
86 | SubmitFailureMessage fm = new SubmitFailureMessage(); | ||
87 | fm.reason = "too early to submit vote (start " | ||
88 | + electionState.ballot.startTime.toFancyString() + ", now " | ||
89 | + AbsoluteTime.now().toFancyString() + ")"; | ||
90 | getSender().send(fm); | ||
91 | } else if (!electionState.ballot.closingTime.isDue()) { | ||
92 | SubmitFailureMessage fm = new SubmitFailureMessage(); | ||
93 | fm.reason = "too late to submit vote"; | ||
94 | getSender().send(fm); | ||
62 | } | 95 | } |
63 | if (m.choiceId < 0 || m.choiceId >= electionState.tally.length) { | 96 | // FIXME: check signatures of voter and CA |
64 | return; | 97 | else { |
98 | electionState.voters.add(m.voterPub); | ||
99 | electionState.tally[m.choiceId] += 1; | ||
100 | SubmitSuccessMessage sm = new SubmitSuccessMessage(); | ||
101 | sm.voucherSig = CryptoECC.Signature.randomSignature(); | ||
102 | getSender().send(sm); | ||
65 | } | 103 | } |
66 | electionState.tally[m.choiceId] += 1; | 104 | |
67 | SubmitResponseMessage rm = new SubmitResponseMessage(); | ||
68 | getSender().send(rm); | ||
69 | getSender().receiveDone(); | 105 | getSender().receiveDone(); |
70 | } | 106 | } |
71 | 107 | ||
72 | public void visit(BallotRegisterRequestMessage m) { | 108 | public void visit(BallotRegisterRequestMessage m) { |
73 | logger.info("ballot register requested"); | 109 | logger.info("ballot register requested"); |
74 | |||
75 | CompressedConfig ccfg = new CompressedConfig(m.compressedBallotConfig); | 110 | CompressedConfig ccfg = new CompressedConfig(m.compressedBallotConfig); |
76 | Ballot b = new Ballot(ccfg.decompress()); | 111 | Ballot b; |
77 | ElectionState electionState = new ElectionState(); | 112 | HashCode guid; |
78 | electionState.tally = new int[b.choices.size()]; | 113 | try { |
79 | electionState.ballot = b; | 114 | b = new Ballot(ccfg.decompress()); |
80 | elections.put(b.getBallotGuid(), electionState); | 115 | guid = b.getBallotGuid(); |
81 | BallotRegisterRespondMessage rm = new BallotRegisterRespondMessage(); | 116 | } catch (InvalidBallotException e) { |
82 | rm.registrationSignature = CryptoECC.Signature.randomSignature(); | 117 | BallotRegisterFailureMessage fm = new BallotRegisterFailureMessage(); |
83 | getSender().send(rm); | 118 | fm.reason = "invalid ballot (" + e.getMessage() + ")"; |
84 | getSender().receiveDone(); | 119 | getSender().send(fm); |
120 | getSender().receiveDone(); | ||
121 | return; | ||
122 | } | ||
123 | if (elections.containsKey(guid)) { | ||
124 | BallotRegisterFailureMessage fm = new BallotRegisterFailureMessage(); | ||
125 | fm.reason = "ballot with same GUID already registered"; | ||
126 | getSender().send(fm); | ||
127 | } else { | ||
128 | ElectionState electionState = new ElectionState(); | ||
129 | electionState.tally = new int[b.choices.size()]; | ||
130 | electionState.ballot = b; | ||
131 | elections.put(guid, electionState); | ||
132 | BallotRegisterSuccessMessage rm = new BallotRegisterSuccessMessage(); | ||
133 | rm.registrationSignature = CryptoECC.Signature.randomSignature(); | ||
134 | getSender().send(rm); | ||
135 | } | ||
136 | |||
85 | } | 137 | } |
86 | 138 | ||
87 | public void visit(QueryMessage m) { | 139 | public void visit(QueryMessage m) { |
88 | ElectionState electionState = elections.get(m.ballotGUID); | 140 | ElectionState electionState = elections.get(m.ballotGUID); |
89 | if (null == electionState) { | 141 | if (null == electionState) { |
90 | QueryFailureMessage rm = new QueryFailureMessage(); | 142 | QueryFailureMessage rm = new QueryFailureMessage(); |
143 | rm.reason = "no matching ballot found"; | ||
91 | getSender().send(rm); | 144 | getSender().send(rm); |
92 | |||
93 | } else { | 145 | } else { |
94 | QueryResponseMessage rm = new QueryResponseMessage(); | 146 | if (electionState.ballot.queryTime.isDue()) { |
95 | rm.results = electionState.tally; | 147 | QueryResponseMessage rm = new QueryResponseMessage(); |
96 | getSender().send(rm); | 148 | rm.results = electionState.tally; |
149 | getSender().send(rm); | ||
150 | } else { | ||
151 | QueryFailureMessage rm = new QueryFailureMessage(); | ||
152 | rm.reason = "result query not allowed yet"; | ||
153 | getSender().send(rm); | ||
154 | } | ||
97 | } | 155 | } |
98 | getSender().receiveDone(); | 156 | getSender().receiveDone(); |
99 | } | 157 | } |
diff --git a/src/main/java/org/gnunet/voting/messages/BallotRegisterFailureMessage.java b/src/main/java/org/gnunet/voting/messages/BallotRegisterFailureMessage.java new file mode 100644 index 0000000..ecce92d --- /dev/null +++ b/src/main/java/org/gnunet/voting/messages/BallotRegisterFailureMessage.java | |||
@@ -0,0 +1,37 @@ | |||
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.NestedMessage; | ||
24 | import org.gnunet.construct.UnionCase; | ||
25 | import org.gnunet.construct.ZeroTerminatedString; | ||
26 | import org.gnunet.util.CryptoECC; | ||
27 | import org.gnunet.util.GnunetMessage; | ||
28 | |||
29 | |||
30 | /** | ||
31 | * Response from the authorities to the issuer. | ||
32 | */ | ||
33 | @UnionCase(42002) | ||
34 | public class BallotRegisterFailureMessage implements GnunetMessage.Body { | ||
35 | @ZeroTerminatedString | ||
36 | public String reason; | ||
37 | } | ||
diff --git a/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java b/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java index 95a7c2f..6dc731f 100644 --- a/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java +++ b/src/main/java/org/gnunet/voting/messages/BallotRegisterRequestMessage.java | |||
@@ -4,6 +4,9 @@ import org.gnunet.construct.IntegerFill; | |||
4 | import org.gnunet.construct.UnionCase; | 4 | import org.gnunet.construct.UnionCase; |
5 | import org.gnunet.util.GnunetMessage; | 5 | import org.gnunet.util.GnunetMessage; |
6 | 6 | ||
7 | /** | ||
8 | * Sent by an issuer to the authorities to register a ballot with them. | ||
9 | */ | ||
7 | @UnionCase(42001) | 10 | @UnionCase(42001) |
8 | public class BallotRegisterRequestMessage implements GnunetMessage.Body { | 11 | public class BallotRegisterRequestMessage implements GnunetMessage.Body { |
9 | @IntegerFill(signed = false, bitSize = 8) | 12 | @IntegerFill(signed = false, bitSize = 8) |
diff --git a/src/main/java/org/gnunet/voting/messages/BallotRegisterRespondMessage.java b/src/main/java/org/gnunet/voting/messages/BallotRegisterSuccessMessage.java index f30f624..8ce007b 100644 --- a/src/main/java/org/gnunet/voting/messages/BallotRegisterRespondMessage.java +++ b/src/main/java/org/gnunet/voting/messages/BallotRegisterSuccessMessage.java | |||
@@ -5,8 +5,12 @@ import org.gnunet.construct.UnionCase; | |||
5 | import org.gnunet.util.CryptoECC; | 5 | import org.gnunet.util.CryptoECC; |
6 | import org.gnunet.util.GnunetMessage; | 6 | import org.gnunet.util.GnunetMessage; |
7 | 7 | ||
8 | @UnionCase(42002) | 8 | |
9 | public class BallotRegisterRespondMessage implements GnunetMessage.Body { | 9 | /** |
10 | * Response from the authorities to the issuer. | ||
11 | */ | ||
12 | @UnionCase(42012) | ||
13 | public class BallotRegisterSuccessMessage implements GnunetMessage.Body { | ||
10 | @NestedMessage | 14 | @NestedMessage |
11 | public CryptoECC.Signature registrationSignature; | 15 | public CryptoECC.Signature registrationSignature; |
12 | } | 16 | } |
diff --git a/src/main/java/org/gnunet/voting/messages/CertificateDenyMessage.java b/src/main/java/org/gnunet/voting/messages/CertificateDenyMessage.java new file mode 100644 index 0000000..aefd6ab --- /dev/null +++ b/src/main/java/org/gnunet/voting/messages/CertificateDenyMessage.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.voting.messages; | ||
22 | |||
23 | |||
24 | import org.gnunet.construct.NestedMessage; | ||
25 | import org.gnunet.construct.UnionCase; | ||
26 | import org.gnunet.construct.ZeroTerminatedString; | ||
27 | import org.gnunet.util.CryptoECC; | ||
28 | import org.gnunet.util.GnunetMessage; | ||
29 | |||
30 | @UnionCase(42011) | ||
31 | public class CertificateDenyMessage implements GnunetMessage.Body { | ||
32 | @ZeroTerminatedString | ||
33 | public String reason; | ||
34 | } | ||
diff --git a/src/main/java/org/gnunet/voting/messages/CertificateGrantMessage.java b/src/main/java/org/gnunet/voting/messages/CertificateGrantMessage.java new file mode 100644 index 0000000..f209b7a --- /dev/null +++ b/src/main/java/org/gnunet/voting/messages/CertificateGrantMessage.java | |||
@@ -0,0 +1,19 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | |||
4 | import org.gnunet.construct.NestedMessage; | ||
5 | import org.gnunet.construct.UInt32; | ||
6 | import org.gnunet.construct.UInt64; | ||
7 | import org.gnunet.construct.UnionCase; | ||
8 | import org.gnunet.util.AbsoluteTime; | ||
9 | import org.gnunet.util.AbsoluteTimeMessage; | ||
10 | import org.gnunet.util.CryptoECC; | ||
11 | import org.gnunet.util.GnunetMessage; | ||
12 | |||
13 | @UnionCase(42004) | ||
14 | public class CertificateGrantMessage implements GnunetMessage.Body { | ||
15 | @NestedMessage | ||
16 | public CryptoECC.Signature groupCertificate; | ||
17 | @NestedMessage | ||
18 | public AbsoluteTimeMessage expiration; | ||
19 | } | ||
diff --git a/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java b/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java index e57b215..1b4514e 100644 --- a/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java +++ b/src/main/java/org/gnunet/voting/messages/CertificateRequestMessage.java | |||
@@ -1,6 +1,8 @@ | |||
1 | package org.gnunet.voting.messages; | 1 | package org.gnunet.voting.messages; |
2 | 2 | ||
3 | import org.gnunet.construct.NestedMessage; | ||
3 | import org.gnunet.construct.UnionCase; | 4 | import org.gnunet.construct.UnionCase; |
5 | import org.gnunet.util.CryptoECC; | ||
4 | import org.gnunet.util.GnunetMessage; | 6 | import org.gnunet.util.GnunetMessage; |
5 | 7 | ||
6 | /** | 8 | /** |
@@ -9,4 +11,13 @@ import org.gnunet.util.GnunetMessage; | |||
9 | */ | 11 | */ |
10 | @UnionCase(42003) | 12 | @UnionCase(42003) |
11 | public class CertificateRequestMessage implements GnunetMessage.Body { | 13 | public class CertificateRequestMessage implements GnunetMessage.Body { |
14 | /** | ||
15 | * Public Key of the voter that requests group certification. | ||
16 | */ | ||
17 | @NestedMessage | ||
18 | public CryptoECC.PublicSignKey publicKey; | ||
19 | /** | ||
20 | * Group that the voter wants to be certified for. | ||
21 | */ | ||
22 | public String group; | ||
12 | } | 23 | } |
diff --git a/src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java b/src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java deleted file mode 100644 index 4a1bcd6..0000000 --- a/src/main/java/org/gnunet/voting/messages/CertificateResponseMessage.java +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | |||
4 | import org.gnunet.construct.UnionCase; | ||
5 | import org.gnunet.util.GnunetMessage; | ||
6 | |||
7 | @UnionCase(42004) | ||
8 | public class CertificateResponseMessage implements GnunetMessage.Body { | ||
9 | } | ||
diff --git a/src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java b/src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java index 73f8fc8..8f525e0 100644 --- a/src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java +++ b/src/main/java/org/gnunet/voting/messages/QueryFailureMessage.java | |||
@@ -21,8 +21,11 @@ | |||
21 | package org.gnunet.voting.messages; | 21 | package org.gnunet.voting.messages; |
22 | 22 | ||
23 | import org.gnunet.construct.UnionCase; | 23 | import org.gnunet.construct.UnionCase; |
24 | import org.gnunet.construct.ZeroTerminatedString; | ||
24 | import org.gnunet.util.GnunetMessage; | 25 | import org.gnunet.util.GnunetMessage; |
25 | 26 | ||
26 | @UnionCase(42009) | 27 | @UnionCase(42009) |
27 | public class QueryFailureMessage implements GnunetMessage.Body { | 28 | public class QueryFailureMessage implements GnunetMessage.Body { |
29 | @ZeroTerminatedString | ||
30 | public String reason; | ||
28 | } | 31 | } |
diff --git a/src/main/java/org/gnunet/voting/messages/SubmitFailureMessage.java b/src/main/java/org/gnunet/voting/messages/SubmitFailureMessage.java new file mode 100644 index 0000000..6e5a345 --- /dev/null +++ b/src/main/java/org/gnunet/voting/messages/SubmitFailureMessage.java | |||
@@ -0,0 +1,32 @@ | |||
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 | |||
24 | import org.gnunet.construct.UnionCase; | ||
25 | import org.gnunet.construct.ZeroTerminatedString; | ||
26 | import org.gnunet.util.GnunetMessage; | ||
27 | |||
28 | @UnionCase(42010) | ||
29 | public class SubmitFailureMessage implements GnunetMessage.Body { | ||
30 | @ZeroTerminatedString | ||
31 | public String reason; | ||
32 | } | ||
diff --git a/src/main/java/org/gnunet/voting/messages/SubmitMessage.java b/src/main/java/org/gnunet/voting/messages/SubmitMessage.java index afd54b9..1b71d3e 100644 --- a/src/main/java/org/gnunet/voting/messages/SubmitMessage.java +++ b/src/main/java/org/gnunet/voting/messages/SubmitMessage.java | |||
@@ -3,17 +3,37 @@ package org.gnunet.voting.messages; | |||
3 | import org.gnunet.construct.NestedMessage; | 3 | import org.gnunet.construct.NestedMessage; |
4 | import org.gnunet.construct.UInt32; | 4 | import org.gnunet.construct.UInt32; |
5 | import org.gnunet.construct.UnionCase; | 5 | import org.gnunet.construct.UnionCase; |
6 | import org.gnunet.construct.ZeroTerminatedString; | 6 | import org.gnunet.util.*; |
7 | import org.gnunet.util.GnunetMessage; | ||
8 | import org.gnunet.util.HashCode; | ||
9 | 7 | ||
10 | /** | 8 | /** |
11 | * Message send by the voter to the election authority to submit a vote. | 9 | * Message send by the voter to the election authority to submit a vote. |
12 | */ | 10 | */ |
13 | @UnionCase(42007) | 11 | @UnionCase(42007) |
14 | public class SubmitMessage implements GnunetMessage.Body { | 12 | public class SubmitMessage implements GnunetMessage.Body { |
13 | /** | ||
14 | * Identifier of the ballot we want to vote in. | ||
15 | */ | ||
15 | @NestedMessage | 16 | @NestedMessage |
16 | public HashCode ballotGuid; | 17 | public HashCode ballotGuid; |
18 | /** | ||
19 | * Public key of the voter. | ||
20 | */ | ||
21 | @NestedMessage | ||
22 | public CryptoECC.PublicSignKey voterPub; | ||
23 | /** | ||
24 | * Group certificate of the voter. | ||
25 | */ | ||
26 | @NestedMessage | ||
27 | public CryptoECC.Signature groupCert; | ||
28 | /** | ||
29 | * Expiration time of the group certificate, checked by the authority. | ||
30 | */ | ||
31 | @NestedMessage | ||
32 | public AbsoluteTimeMessage groupCertExpiration; | ||
33 | /** | ||
34 | * The actual vote. | ||
35 | * FIXME: this will be encrypted! | ||
36 | */ | ||
17 | @UInt32 | 37 | @UInt32 |
18 | public int choiceId; | 38 | public int choiceId; |
19 | } | 39 | } |
diff --git a/src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java b/src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java deleted file mode 100644 index 956ecf2..0000000 --- a/src/main/java/org/gnunet/voting/messages/SubmitResponseMessage.java +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | |||
4 | import org.gnunet.construct.UnionCase; | ||
5 | import org.gnunet.util.GnunetMessage; | ||
6 | |||
7 | @UnionCase(42008) | ||
8 | public class SubmitResponseMessage implements GnunetMessage.Body { | ||
9 | } | ||
diff --git a/src/main/java/org/gnunet/voting/messages/SubmitSuccessMessage.java b/src/main/java/org/gnunet/voting/messages/SubmitSuccessMessage.java new file mode 100644 index 0000000..0c0e9e1 --- /dev/null +++ b/src/main/java/org/gnunet/voting/messages/SubmitSuccessMessage.java | |||
@@ -0,0 +1,13 @@ | |||
1 | package org.gnunet.voting.messages; | ||
2 | |||
3 | |||
4 | import org.gnunet.construct.NestedMessage; | ||
5 | import org.gnunet.construct.UnionCase; | ||
6 | import org.gnunet.util.CryptoECC; | ||
7 | import org.gnunet.util.GnunetMessage; | ||
8 | |||
9 | @UnionCase(42008) | ||
10 | public class SubmitSuccessMessage implements GnunetMessage.Body { | ||
11 | @NestedMessage | ||
12 | public CryptoECC.Signature voucherSig; | ||
13 | } | ||
diff --git a/src/main/resources/org/gnunet/construct/MsgMap.txt b/src/main/resources/org/gnunet/construct/MsgMap.txt index 8f427b7..2b68b18 100644 --- a/src/main/resources/org/gnunet/construct/MsgMap.txt +++ b/src/main/resources/org/gnunet/construct/MsgMap.txt | |||
@@ -1,31 +1,37 @@ | |||
1 | org.gnunet.util.Resolver$Address|0=org.gnunet.util.Resolver$TextualAddress | 1 | org.gnunet.util.Resolver$Address|0=org.gnunet.util.Resolver$TextualAddress |
2 | org.gnunet.util.Resolver$Address|1=org.gnunet.util.Resolver$NumericAddress | 2 | org.gnunet.util.Resolver$Address|1=org.gnunet.util.Resolver$NumericAddress |
3 | org.gnunet.util.GnunetMessage$Body|1=org.gnunet.util.TestMessage | ||
4 | org.gnunet.util.GnunetMessage$Body|274=org.gnunet.mesh.TunnelDestroyMessage | 3 | org.gnunet.util.GnunetMessage$Body|274=org.gnunet.mesh.TunnelDestroyMessage |
4 | org.gnunet.util.GnunetMessage$Body|1=org.gnunet.util.TestMessage | ||
5 | org.gnunet.util.GnunetMessage$Body|273=org.gnunet.mesh.TunnelCreateMessage | 5 | org.gnunet.util.GnunetMessage$Body|273=org.gnunet.mesh.TunnelCreateMessage |
6 | org.gnunet.util.GnunetMessage$Body|272=org.gnunet.mesh.ClientConnectMessage | 6 | org.gnunet.util.GnunetMessage$Body|272=org.gnunet.mesh.ClientConnectMessage |
7 | org.gnunet.util.GnunetMessage$Body|4=org.gnunet.util.Resolver$GetMessage | 7 | org.gnunet.util.GnunetMessage$Body|4=org.gnunet.util.Resolver$GetMessage |
8 | org.gnunet.util.GnunetMessage$Body|5=org.gnunet.util.Resolver$ResolverResponse | 8 | org.gnunet.util.GnunetMessage$Body|5=org.gnunet.util.Resolver$ResolverResponse |
9 | org.gnunet.util.GnunetMessage$Body|143=org.gnunet.dht.ClientGetMessage | 9 | org.gnunet.util.GnunetMessage$Body|143=org.gnunet.dht.ClientGetMessage |
10 | org.gnunet.util.GnunetMessage$Body|142=org.gnunet.dht.ClientPutMessage | 10 | org.gnunet.util.GnunetMessage$Body|142=org.gnunet.dht.ClientPutMessage |
11 | org.gnunet.util.GnunetMessage$Body|10=org.gnunet.arm.messages.ResultMessage | ||
12 | org.gnunet.util.GnunetMessage$Body|11=org.gnunet.arm.messages.StatusMessage | ||
11 | org.gnunet.util.GnunetMessage$Body|286=org.gnunet.mesh.LocalAckMessage | 13 | org.gnunet.util.GnunetMessage$Body|286=org.gnunet.mesh.LocalAckMessage |
14 | org.gnunet.util.GnunetMessage$Body|13=org.gnunet.arm.messages.ListResultMessage | ||
12 | org.gnunet.util.GnunetMessage$Body|285=org.gnunet.mesh.DataMessage | 15 | org.gnunet.util.GnunetMessage$Body|285=org.gnunet.mesh.DataMessage |
13 | org.gnunet.util.GnunetMessage$Body|42003=org.gnunet.voting.messages.CertificateRequestMessage | 16 | org.gnunet.util.GnunetMessage$Body|42003=org.gnunet.voting.messages.CertificateRequestMessage |
14 | org.gnunet.util.GnunetMessage$Body|153=org.gnunet.dht.MonitorStartStop | 17 | org.gnunet.util.GnunetMessage$Body|153=org.gnunet.dht.MonitorStartStop |
15 | org.gnunet.util.GnunetMessage$Body|42002=org.gnunet.voting.messages.BallotRegisterRespondMessage | 18 | org.gnunet.util.GnunetMessage$Body|42002=org.gnunet.voting.messages.BallotRegisterFailureMessage |
16 | org.gnunet.util.GnunetMessage$Body|42001=org.gnunet.voting.messages.BallotRegisterRequestMessage | 19 | org.gnunet.util.GnunetMessage$Body|42001=org.gnunet.voting.messages.BallotRegisterRequestMessage |
17 | org.gnunet.util.GnunetMessage$Body|155=org.gnunet.dht.ClientPutConfirmationMessage | 20 | org.gnunet.util.GnunetMessage$Body|155=org.gnunet.dht.ClientPutConfirmationMessage |
18 | org.gnunet.util.GnunetMessage$Body|42007=org.gnunet.voting.messages.SubmitMessage | 21 | org.gnunet.util.GnunetMessage$Body|42007=org.gnunet.voting.messages.SubmitMessage |
19 | org.gnunet.util.GnunetMessage$Body|42006=org.gnunet.voting.messages.QueryResponseMessage | 22 | org.gnunet.util.GnunetMessage$Body|42006=org.gnunet.voting.messages.QueryResponseMessage |
20 | org.gnunet.util.GnunetMessage$Body|42005=org.gnunet.voting.messages.QueryMessage | 23 | org.gnunet.util.GnunetMessage$Body|42005=org.gnunet.voting.messages.QueryMessage |
21 | org.gnunet.util.GnunetMessage$Body|42004=org.gnunet.voting.messages.CertificateResponseMessage | 24 | org.gnunet.util.GnunetMessage$Body|42004=org.gnunet.voting.messages.CertificateGrantMessage |
25 | org.gnunet.util.GnunetMessage$Body|42011=org.gnunet.voting.messages.CertificateDenyMessage | ||
22 | org.gnunet.util.GnunetMessage$Body|144=org.gnunet.dht.ClientGetStopMessage | 26 | org.gnunet.util.GnunetMessage$Body|144=org.gnunet.dht.ClientGetStopMessage |
23 | org.gnunet.util.GnunetMessage$Body|145=org.gnunet.dht.ClientResultMessage | 27 | org.gnunet.util.GnunetMessage$Body|145=org.gnunet.dht.ClientResultMessage |
28 | org.gnunet.util.GnunetMessage$Body|42010=org.gnunet.voting.messages.SubmitFailureMessage | ||
24 | org.gnunet.util.GnunetMessage$Body|42009=org.gnunet.voting.messages.QueryFailureMessage | 29 | org.gnunet.util.GnunetMessage$Body|42009=org.gnunet.voting.messages.QueryFailureMessage |
25 | org.gnunet.util.GnunetMessage$Body|42008=org.gnunet.voting.messages.SubmitResponseMessage | 30 | org.gnunet.util.GnunetMessage$Body|42008=org.gnunet.voting.messages.SubmitSuccessMessage |
26 | org.gnunet.util.GnunetMessage$Body|149=org.gnunet.dht.MonitorGetMessage | 31 | org.gnunet.util.GnunetMessage$Body|149=org.gnunet.dht.MonitorGetMessage |
27 | org.gnunet.util.GnunetMessage$Body|150=org.gnunet.dht.MonitorGetRespMessage | 32 | org.gnunet.util.GnunetMessage$Body|150=org.gnunet.dht.MonitorGetRespMessage |
28 | org.gnunet.util.GnunetMessage$Body|151=org.gnunet.dht.MonitorPutMessage | 33 | org.gnunet.util.GnunetMessage$Body|151=org.gnunet.dht.MonitorPutMessage |
34 | org.gnunet.util.GnunetMessage$Body|42012=org.gnunet.voting.messages.BallotRegisterSuccessMessage | ||
29 | org.gnunet.util.GnunetMessage$Body|171=org.gnunet.statistics.GetResponseEndMessage | 35 | org.gnunet.util.GnunetMessage$Body|171=org.gnunet.statistics.GetResponseEndMessage |
30 | org.gnunet.util.GnunetMessage$Body|170=org.gnunet.statistics.GetResponseMessage | 36 | org.gnunet.util.GnunetMessage$Body|170=org.gnunet.statistics.GetResponseMessage |
31 | org.gnunet.util.GnunetMessage$Body|169=org.gnunet.statistics.GetMessage | 37 | org.gnunet.util.GnunetMessage$Body|169=org.gnunet.statistics.GetMessage |
@@ -57,9 +63,17 @@ org.gnunet.util.GnunetMessage$Body|74=org.gnunet.core.SendMessageRequest | |||
57 | org.gnunet.util.GnunetMessage$Body|464=org.gnunet.testbed.messages.PeerCreateMessage | 63 | org.gnunet.util.GnunetMessage$Body|464=org.gnunet.testbed.messages.PeerCreateMessage |
58 | org.gnunet.util.GnunetMessage$Body|75=org.gnunet.core.SendMessageReady | 64 | org.gnunet.util.GnunetMessage$Body|75=org.gnunet.core.SendMessageReady |
59 | org.gnunet.util.GnunetMessage$Body|465=org.gnunet.testbed.messages.PeerReconfigureMessage | 65 | org.gnunet.util.GnunetMessage$Body|465=org.gnunet.testbed.messages.PeerReconfigureMessage |
66 | org.gnunet.util.GnunetMessage$Body|627=org.gnunet.identity.messages.GetDefaultMessage | ||
67 | org.gnunet.util.GnunetMessage$Body|626=org.gnunet.identity.messages.UpdateListMessage | ||
68 | org.gnunet.util.GnunetMessage$Body|625=org.gnunet.identity.messages.ResultCodeMessage | ||
60 | org.gnunet.util.GnunetMessage$Body|460=org.gnunet.testbed.messages.ControllerInitMessage | 69 | org.gnunet.util.GnunetMessage$Body|460=org.gnunet.testbed.messages.ControllerInitMessage |
70 | org.gnunet.util.GnunetMessage$Body|624=org.gnunet.identity.messages.StartMessage | ||
71 | org.gnunet.util.GnunetMessage$Body|631=org.gnunet.identity.messages.DeleteMessage | ||
72 | org.gnunet.util.GnunetMessage$Body|630=org.gnunet.identity.messages.RenameMessage | ||
61 | org.gnunet.util.GnunetMessage$Body|323=org.gnunet.nse.UpdateMessage | 73 | org.gnunet.util.GnunetMessage$Body|323=org.gnunet.nse.UpdateMessage |
74 | org.gnunet.util.GnunetMessage$Body|629=org.gnunet.identity.messages.CreateRequestMessage | ||
62 | org.gnunet.util.GnunetMessage$Body|321=org.gnunet.nse.StartMessage | 75 | org.gnunet.util.GnunetMessage$Body|321=org.gnunet.nse.StartMessage |
76 | org.gnunet.util.GnunetMessage$Body|628=org.gnunet.identity.messages.SetDefaultMessage | ||
63 | org.gnunet.util.GnunetMessage$Body|332=org.gnunet.peerinfo.InfoMessage | 77 | org.gnunet.util.GnunetMessage$Body|332=org.gnunet.peerinfo.InfoMessage |
64 | org.gnunet.util.GnunetMessage$Body|333=org.gnunet.peerinfo.InfoEnd | 78 | org.gnunet.util.GnunetMessage$Body|333=org.gnunet.peerinfo.InfoEnd |
65 | org.gnunet.util.GnunetMessage$Body|331=org.gnunet.peerinfo.ListAllPeersMessage | 79 | org.gnunet.util.GnunetMessage$Body|331=org.gnunet.peerinfo.ListAllPeersMessage |
@@ -73,4 +87,4 @@ org.gnunet.util.GnunetMessage$Body|495=org.gnunet.testbed.messages.HelperInitMes | |||
73 | org.gnunet.util.GnunetMessage$Body|360=org.gnunet.transport.StartMessage | 87 | org.gnunet.util.GnunetMessage$Body|360=org.gnunet.transport.StartMessage |
74 | org.gnunet.util.GnunetMessage$Body|483=org.gnunet.testbed.messages.ManagePeerServiceMessage | 88 | org.gnunet.util.GnunetMessage$Body|483=org.gnunet.testbed.messages.ManagePeerServiceMessage |
75 | org.gnunet.construct.MessageUnion|525=org.gnunet.consensus.ConcludeDoneMessage | 89 | org.gnunet.construct.MessageUnion|525=org.gnunet.consensus.ConcludeDoneMessage |
76 | # generated 2013/09/25 01:34:20 | 90 | # generated 2013/10/08 22:01:30 |
diff --git a/src/main/resources/org/gnunet/voting/template.espec b/src/main/resources/org/gnunet/voting/template.espec index 292887a..9af5a79 100644 --- a/src/main/resources/org/gnunet/voting/template.espec +++ b/src/main/resources/org/gnunet/voting/template.espec | |||
@@ -9,20 +9,23 @@ TOPIC = | |||
9 | # choices for the voter, separated by a double slash | 9 | # choices for the voter, separated by a double slash |
10 | CHOICES = yes//no | 10 | CHOICES = yes//no |
11 | 11 | ||
12 | # group of elegible voters, voters must be certified by the CA to | ||
13 | # belong to this group | ||
14 | GROUP = | ||
15 | |||
12 | # starting time of the election, in the local time of the election issuer | 16 | # starting time of the election, in the local time of the election issuer |
13 | # authorities affirm that they are available for the election from this point in time | 17 | # authorities affirm that they are available for the election from this point in time |
14 | ELECTION_START = | 18 | TIME_START = |
15 | 19 | ||
16 | # election start time, as posix time stamp | 20 | # what is the deadline for vote submission? |
17 | # ELECTION_START_POSIX | 21 | # after this deadline, authorities work together to count ballots |
22 | TIME_CLOSING = | ||
18 | 23 | ||
19 | # deadline for vote submission, in the local time of the election issuer | 24 | # when may results be queried? |
20 | # must be later than ELECTION_START | 25 | TIME_QUERY = |
21 | ELECTION_END = | ||
22 | 26 | ||
23 | # At what time must an authority complete round X of the voting protocol | 27 | # FIXME: specify more parameters for consensus? which ones? |
24 | # (fixme: need to define exactly which rounds there will be...) | 28 | # CONSENSUS_PARAMETERS = |
25 | AUTHORITY_ROUND_X_TIME = | ||
26 | 29 | ||
27 | # public key of the certificate authority | 30 | # public key of the certificate authority |
28 | CA_PUB = | 31 | CA_PUB = |
@@ -48,14 +51,8 @@ CA_PUB = | |||
48 | # ISSUER_SIGNATURE = | 51 | # ISSUER_SIGNATURE = |
49 | 52 | ||
50 | 53 | ||
51 | [voter] | 54 | [vote] |
52 | # before a voter can submit his vote, the permission to do so | 55 | # voter signature, pubkey, group cert, |
53 | # must be given by the certificate authority of the election | ||
54 | # VOTER_PUB = ... | ||
55 | # VOTER_CERT = ... | ||
56 | |||
57 | |||
58 | [vote-data] | ||
59 | # encrypted vote and non-interactive zero knowledge proofs come here | 56 | # encrypted vote and non-interactive zero knowledge proofs come here |
60 | 57 | ||
61 | 58 | ||
diff --git a/src/test/java/org/gnunet/identity/IdentityTest.java b/src/test/java/org/gnunet/identity/IdentityTest.java new file mode 100644 index 0000000..cda4e6b --- /dev/null +++ b/src/test/java/org/gnunet/identity/IdentityTest.java | |||
@@ -0,0 +1,123 @@ | |||
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.identity; | ||
22 | |||
23 | |||
24 | import org.gnunet.testing.TestingSubsystem; | ||
25 | import org.gnunet.util.Program; | ||
26 | import org.gnunet.util.Scheduler; | ||
27 | import org.gnunet.util.Wrapper; | ||
28 | import org.junit.Assert; | ||
29 | import org.junit.Test; | ||
30 | |||
31 | public class IdentityTest { | ||
32 | @Test | ||
33 | public void test_identity_connect() { | ||
34 | final Wrapper<Boolean> reachedEnd = new Wrapper<Boolean>(false); | ||
35 | Program.configureLogging("DEBUG"); | ||
36 | TestingSubsystem ts = new TestingSubsystem("identity"); | ||
37 | |||
38 | final Identity identity = new Identity(); | ||
39 | identity.connect(ts.getConfiguration(), new IdentityListCallback() { | ||
40 | @Override | ||
41 | public void onEgoAdd(Identity.Ego ego) { | ||
42 | System.out.println("got ego " + ego.getName()); | ||
43 | } | ||
44 | |||
45 | @Override | ||
46 | public void onEgoDelete(Identity.Ego ego) { | ||
47 | // should only happen after end of list, | ||
48 | // but we disconnect on end of list | ||
49 | Assert.fail(); | ||
50 | } | ||
51 | |||
52 | @Override | ||
53 | public void onEgoRename(String oldName, Identity.Ego ego) { | ||
54 | Assert.fail(); | ||
55 | } | ||
56 | |||
57 | @Override | ||
58 | public void onListEnd() { | ||
59 | System.out.println("got end of list"); | ||
60 | reachedEnd.set(true); | ||
61 | identity.disconnect(); | ||
62 | } | ||
63 | }); | ||
64 | Scheduler.run(); | ||
65 | Assert.assertTrue(reachedEnd.get()); | ||
66 | } | ||
67 | |||
68 | @Test | ||
69 | public void test_identity_create() { | ||
70 | final Wrapper<Boolean> created = new Wrapper<Boolean>(false); | ||
71 | final Wrapper<Boolean> gotEnd = new Wrapper<Boolean>(false); | ||
72 | final Wrapper<Boolean> gotCreated = new Wrapper<Boolean>(false); | ||
73 | Program.configureLogging("DEBUG"); | ||
74 | TestingSubsystem ts = new TestingSubsystem("identity"); | ||
75 | |||
76 | final String myEgoName = "gnunet-java-test-ego"; | ||
77 | |||
78 | final Identity identity = new Identity(); | ||
79 | identity.connect(ts.getConfiguration(), new IdentityListCallback() { | ||
80 | @Override | ||
81 | public void onEgoAdd(Identity.Ego ego) { | ||
82 | if (created.get() && ego.getName().equals(myEgoName)) { | ||
83 | gotCreated.set(true); | ||
84 | identity.disconnect(); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | @Override | ||
89 | public void onEgoDelete(Identity.Ego ego) { | ||
90 | // should only happen after end of list, | ||
91 | // but we disconnect on end of list | ||
92 | Assert.fail(); | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public void onEgoRename(String oldName, Identity.Ego ego) { | ||
97 | Assert.fail(); | ||
98 | } | ||
99 | |||
100 | @Override | ||
101 | public void onListEnd() { | ||
102 | System.out.println("got end of list"); | ||
103 | gotEnd.set(true); | ||
104 | } | ||
105 | }); | ||
106 | identity.create(myEgoName, new IdentityContinuation() { | ||
107 | @Override | ||
108 | public void onError(String errorMessage) { | ||
109 | Assert.fail(errorMessage); | ||
110 | } | ||
111 | |||
112 | @Override | ||
113 | public void onDone() { | ||
114 | Assert.assertFalse(created.get()); | ||
115 | created.set(true); | ||
116 | } | ||
117 | }); | ||
118 | Scheduler.run(); | ||
119 | Assert.assertTrue(created.get()); | ||
120 | Assert.assertTrue(gotCreated.get()); | ||
121 | Assert.assertTrue(gotEnd.get()); | ||
122 | } | ||
123 | } | ||
diff --git a/src/test/java/org/gnunet/testbed/TestbedTest.java b/src/test/java/org/gnunet/testbed/TestbedTest.java index 56febde..6a6ed10 100644 --- a/src/test/java/org/gnunet/testbed/TestbedTest.java +++ b/src/test/java/org/gnunet/testbed/TestbedTest.java | |||
@@ -12,7 +12,7 @@ import org.junit.Test; | |||
12 | 12 | ||
13 | public class TestbedTest extends TestingFixture { | 13 | public class TestbedTest extends TestingFixture { |
14 | 14 | ||
15 | @Test(timeout = 1000) | 15 | @Test(timeout = 10000) |
16 | public void test_controller_proc() { | 16 | public void test_controller_proc() { |
17 | final Wrapper<Boolean> success = new Wrapper<Boolean>(false); | 17 | final Wrapper<Boolean> success = new Wrapper<Boolean>(false); |
18 | new Program("-LDEBUG") { | 18 | new Program("-LDEBUG") { |
@@ -38,16 +38,13 @@ public class TestbedTest extends TestingFixture { | |||
38 | } | 38 | } |
39 | 39 | ||
40 | 40 | ||
41 | @Test(timeout = 1000) | 41 | @Test(timeout = 10000) |
42 | public void test_peer_create() { | 42 | public void test_peer_create() { |
43 | new Program("-LDEBUG") { | 43 | new Program("-LDEBUG") { |
44 | ControllerProc cp; | 44 | ControllerProc cp; |
45 | Host h; | 45 | Host h; |
46 | Controller c; | 46 | Controller c; |
47 | 47 | ||
48 | class CEC extends ControllerEventCallback { | ||
49 | } | ||
50 | |||
51 | class PCB implements PeerCreateCallback { | 48 | class PCB implements PeerCreateCallback { |
52 | @Override | 49 | @Override |
53 | public void onPeerCreated(Controller.Peer peer) { | 50 | public void onPeerCreated(Controller.Peer peer) { |
@@ -71,7 +68,7 @@ public class TestbedTest extends TestingFixture { | |||
71 | @Override | 68 | @Override |
72 | public void onStartupSuccess(Configuration cfg) { | 69 | public void onStartupSuccess(Configuration cfg) { |
73 | System.out.println("startup success"); | 70 | System.out.println("startup success"); |
74 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 71 | c = new Controller(h); |
75 | // FIXME: use config from resource | 72 | // FIXME: use config from resource |
76 | c.createPeer(h, getConfiguration(), new PCB()); | 73 | c.createPeer(h, getConfiguration(), new PCB()); |
77 | } | 74 | } |
@@ -84,16 +81,13 @@ public class TestbedTest extends TestingFixture { | |||
84 | }.start(); | 81 | }.start(); |
85 | } | 82 | } |
86 | 83 | ||
87 | @Test(timeout = 1000) | 84 | @Test(timeout = 10000) |
88 | public void test_peer_destroy() { | 85 | public void test_peer_destroy() { |
89 | new Program("-LDEBUG") { | 86 | new Program("-LDEBUG") { |
90 | ControllerProc cp; | 87 | ControllerProc cp; |
91 | Host h; | 88 | Host h; |
92 | Controller c; | 89 | Controller c; |
93 | 90 | ||
94 | class CEC extends ControllerEventCallback { | ||
95 | } | ||
96 | |||
97 | class PCB implements PeerCreateCallback { | 91 | class PCB implements PeerCreateCallback { |
98 | @Override | 92 | @Override |
99 | public void onPeerCreated(final Controller.Peer peer) { | 93 | public void onPeerCreated(final Controller.Peer peer) { |
@@ -128,7 +122,7 @@ public class TestbedTest extends TestingFixture { | |||
128 | @Override | 122 | @Override |
129 | public void onStartupSuccess(Configuration cfg) { | 123 | public void onStartupSuccess(Configuration cfg) { |
130 | System.out.println("startup success"); | 124 | System.out.println("startup success"); |
131 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 125 | c = new Controller(h); |
132 | // FIXME: use config from resource | 126 | // FIXME: use config from resource |
133 | c.createPeer(h, getConfiguration(), new PCB()); | 127 | c.createPeer(h, getConfiguration(), new PCB()); |
134 | } | 128 | } |
@@ -141,7 +135,7 @@ public class TestbedTest extends TestingFixture { | |||
141 | }.start(); | 135 | }.start(); |
142 | } | 136 | } |
143 | 137 | ||
144 | @Test(timeout = 5000) | 138 | @Test(timeout = 10000) |
145 | public void test_peer_start() { | 139 | public void test_peer_start() { |
146 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); | 140 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); |
147 | int ret = new Program("-LDEBUG") { | 141 | int ret = new Program("-LDEBUG") { |
@@ -149,9 +143,6 @@ public class TestbedTest extends TestingFixture { | |||
149 | Host h; | 143 | Host h; |
150 | Controller c; | 144 | Controller c; |
151 | 145 | ||
152 | class CEC extends ControllerEventCallback { | ||
153 | } | ||
154 | |||
155 | class MyPeerChurnCallback implements PeerChurnCallback { | 146 | class MyPeerChurnCallback implements PeerChurnCallback { |
156 | 147 | ||
157 | @Override | 148 | @Override |
@@ -190,7 +181,7 @@ public class TestbedTest extends TestingFixture { | |||
190 | @Override | 181 | @Override |
191 | public void onStartupSuccess(Configuration cfg) { | 182 | public void onStartupSuccess(Configuration cfg) { |
192 | System.out.println("controller started"); | 183 | System.out.println("controller started"); |
193 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 184 | c = new Controller(h); |
194 | // FIXME: use config from resource | 185 | // FIXME: use config from resource |
195 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); | 186 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); |
196 | } | 187 | } |
@@ -205,7 +196,7 @@ public class TestbedTest extends TestingFixture { | |||
205 | Assert.assertEquals(0, ret); | 196 | Assert.assertEquals(0, ret); |
206 | } | 197 | } |
207 | 198 | ||
208 | @Test(timeout = 5000) | 199 | @Test(timeout = 10000) |
209 | public void test_peer_stop() { | 200 | public void test_peer_stop() { |
210 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); | 201 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); |
211 | final Wrapper<Boolean> stopSuccessful = new Wrapper<Boolean>(false); | 202 | final Wrapper<Boolean> stopSuccessful = new Wrapper<Boolean>(false); |
@@ -215,9 +206,6 @@ public class TestbedTest extends TestingFixture { | |||
215 | Controller c; | 206 | Controller c; |
216 | Controller.Peer p; | 207 | Controller.Peer p; |
217 | 208 | ||
218 | class CEC extends ControllerEventCallback { | ||
219 | } | ||
220 | |||
221 | class MyPeerStopCallback implements PeerChurnCallback { | 209 | class MyPeerStopCallback implements PeerChurnCallback { |
222 | 210 | ||
223 | @Override | 211 | @Override |
@@ -271,7 +259,7 @@ public class TestbedTest extends TestingFixture { | |||
271 | @Override | 259 | @Override |
272 | public void onStartupSuccess(Configuration cfg) { | 260 | public void onStartupSuccess(Configuration cfg) { |
273 | System.out.println("controller started"); | 261 | System.out.println("controller started"); |
274 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 262 | c = new Controller(h); |
275 | // FIXME: use config from resource | 263 | // FIXME: use config from resource |
276 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); | 264 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); |
277 | } | 265 | } |
@@ -287,7 +275,7 @@ public class TestbedTest extends TestingFixture { | |||
287 | Assert.assertEquals(0, ret); | 275 | Assert.assertEquals(0, ret); |
288 | } | 276 | } |
289 | 277 | ||
290 | @Test(timeout = 5000) | 278 | @Test(timeout = 10000) |
291 | public void test_peer_stop_destroy() { | 279 | public void test_peer_stop_destroy() { |
292 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); | 280 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); |
293 | final Wrapper<Boolean> stopSuccessful = new Wrapper<Boolean>(false); | 281 | final Wrapper<Boolean> stopSuccessful = new Wrapper<Boolean>(false); |
@@ -298,9 +286,6 @@ public class TestbedTest extends TestingFixture { | |||
298 | Controller c; | 286 | Controller c; |
299 | Controller.Peer p; | 287 | Controller.Peer p; |
300 | 288 | ||
301 | class CEC extends ControllerEventCallback { | ||
302 | } | ||
303 | |||
304 | class MyPeerDestroyCallback implements OperationCompletionCallback { | 289 | class MyPeerDestroyCallback implements OperationCompletionCallback { |
305 | 290 | ||
306 | @Override | 291 | @Override |
@@ -367,7 +352,7 @@ public class TestbedTest extends TestingFixture { | |||
367 | @Override | 352 | @Override |
368 | public void onStartupSuccess(Configuration cfg) { | 353 | public void onStartupSuccess(Configuration cfg) { |
369 | System.out.println("controller started"); | 354 | System.out.println("controller started"); |
370 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 355 | c = new Controller(h); |
371 | // FIXME: use config from resource | 356 | // FIXME: use config from resource |
372 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); | 357 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); |
373 | } | 358 | } |
@@ -394,9 +379,6 @@ public class TestbedTest extends TestingFixture { | |||
394 | Controller c; | 379 | Controller c; |
395 | Controller.Peer p; | 380 | Controller.Peer p; |
396 | 381 | ||
397 | class CEC extends ControllerEventCallback { | ||
398 | } | ||
399 | |||
400 | class MyPeerInformationCallback implements PeerInformationCallback { | 382 | class MyPeerInformationCallback implements PeerInformationCallback { |
401 | @Override | 383 | @Override |
402 | public void onSuccess(PeerIdentity peerIdentity, Configuration configuration) { | 384 | public void onSuccess(PeerIdentity peerIdentity, Configuration configuration) { |
@@ -433,7 +415,7 @@ public class TestbedTest extends TestingFixture { | |||
433 | @Override | 415 | @Override |
434 | public void onStartupSuccess(Configuration cfg) { | 416 | public void onStartupSuccess(Configuration cfg) { |
435 | System.out.println("controller started"); | 417 | System.out.println("controller started"); |
436 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 418 | c = new Controller(h); |
437 | // FIXME: use config from resource | 419 | // FIXME: use config from resource |
438 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); | 420 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback()); |
439 | } | 421 | } |
@@ -449,10 +431,9 @@ public class TestbedTest extends TestingFixture { | |||
449 | Assert.assertEquals(0, ret); | 431 | Assert.assertEquals(0, ret); |
450 | } | 432 | } |
451 | 433 | ||
452 | @Test(timeout = 5000) | 434 | @Test |
453 | public void test_peer_reconfigure() { | 435 | public void test_peer_reconfigure() { |
454 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); | 436 | final Wrapper<Boolean> startSuccessful = new Wrapper<Boolean>(false); |
455 | final Wrapper<Boolean> infoSuccessful = new Wrapper<Boolean>(false); | ||
456 | final Wrapper<Boolean> reconfigureSuccessful = new Wrapper<Boolean>(false); | 437 | final Wrapper<Boolean> reconfigureSuccessful = new Wrapper<Boolean>(false); |
457 | int ret = new Program("-LDEBUG") { | 438 | int ret = new Program("-LDEBUG") { |
458 | ControllerProc cp; | 439 | ControllerProc cp; |
@@ -460,9 +441,6 @@ public class TestbedTest extends TestingFixture { | |||
460 | Controller c; | 441 | Controller c; |
461 | Controller.Peer p; | 442 | Controller.Peer p; |
462 | 443 | ||
463 | class CEC extends ControllerEventCallback { | ||
464 | } | ||
465 | |||
466 | class MyUpdateConfigDoneCallback implements OperationCompletionCallback { | 444 | class MyUpdateConfigDoneCallback implements OperationCompletionCallback { |
467 | @Override | 445 | @Override |
468 | public void onCompletion() { | 446 | public void onCompletion() { |
@@ -478,30 +456,15 @@ public class TestbedTest extends TestingFixture { | |||
478 | } | 456 | } |
479 | } | 457 | } |
480 | 458 | ||
481 | /* | ||
482 | class MyPeerInformationCallback implements PeerInformationCallback { | ||
483 | @Override | ||
484 | public void onSuccess(PeerIdentity peerIdentity, Configuration configuration) { | ||
485 | Assert.assertNotNull(peerIdentity); | ||
486 | Assert.assertNotNull(configuration); | ||
487 | Assert.assertTrue(configuration.getSections().size() > 0); | ||
488 | infoSuccessful.set(true); | ||
489 | System.out.println("updating configuration"); | ||
490 | p.updateConfiguration(cfg, new MyUpdateConfigDoneCallback()); | ||
491 | } | ||
492 | } | ||
493 | |||
494 | */ | ||
495 | |||
496 | class MyPeerCreateCallback implements PeerCreateCallback { | 459 | class MyPeerCreateCallback implements PeerCreateCallback { |
497 | @Override | 460 | @Override |
498 | public void onPeerCreated(Controller.Peer peer) { | 461 | public void onPeerCreated(Controller.Peer peer) { |
499 | p = peer; | 462 | p = peer; |
500 | System.out.println("peer created"); | 463 | System.out.println("peer created"); |
501 | startSuccessful.set(true); | 464 | startSuccessful.set(true); |
502 | //peer.requestInformation(new MyPeerInformationCallback()); | ||
503 | 465 | ||
504 | Configuration cfg = new Configuration(); | 466 | Configuration cfg = new Configuration(); |
467 | cfg.setValueNumber("foo", "bar", 42); | ||
505 | cfg.setValueString("my-test-section", "my-test-option", "my-test-value"); | 468 | cfg.setValueString("my-test-section", "my-test-option", "my-test-value"); |
506 | peer.updateConfiguration(cfg, new MyUpdateConfigDoneCallback()); | 469 | peer.updateConfiguration(cfg, new MyUpdateConfigDoneCallback()); |
507 | } | 470 | } |
@@ -522,7 +485,7 @@ public class TestbedTest extends TestingFixture { | |||
522 | @Override | 485 | @Override |
523 | public void onStartupSuccess(Configuration cfg) { | 486 | public void onStartupSuccess(Configuration cfg) { |
524 | System.out.println("controller started"); | 487 | System.out.println("controller started"); |
525 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 488 | c = new Controller(h); |
526 | // FIXME: use config from resource | 489 | // FIXME: use config from resource |
527 | c.createPeer(h, configuration, new MyPeerCreateCallback()); | 490 | c.createPeer(h, configuration, new MyPeerCreateCallback()); |
528 | } | 491 | } |
@@ -549,9 +512,6 @@ public class TestbedTest extends TestingFixture { | |||
549 | Controller.Peer p1; | 512 | Controller.Peer p1; |
550 | int peersStarted = 0; | 513 | int peersStarted = 0; |
551 | 514 | ||
552 | class CEC extends ControllerEventCallback { | ||
553 | } | ||
554 | |||
555 | class MyConnectCompleteCallback implements OperationCompletionCallback { | 515 | class MyConnectCompleteCallback implements OperationCompletionCallback { |
556 | 516 | ||
557 | @Override | 517 | @Override |
@@ -620,7 +580,7 @@ public class TestbedTest extends TestingFixture { | |||
620 | @Override | 580 | @Override |
621 | public void onStartupSuccess(Configuration cfg) { | 581 | public void onStartupSuccess(Configuration cfg) { |
622 | System.out.println("controller started"); | 582 | System.out.println("controller started"); |
623 | c = new Controller(h, 1 | 2 | 4 | 8 | 32, new CEC()); | 583 | c = new Controller(h); |
624 | // FIXME: use config from resource | 584 | // FIXME: use config from resource |
625 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback(0)); | 585 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback(0)); |
626 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback(1)); | 586 | c.createPeer(h, getConfiguration(), new MyPeerCreateCallback(1)); |
diff --git a/src/test/java/org/gnunet/util/CryptoECCTest.java b/src/test/java/org/gnunet/util/CryptoECCTest.java index c4c85d2..1dda545 100644 --- a/src/test/java/org/gnunet/util/CryptoECCTest.java +++ b/src/test/java/org/gnunet/util/CryptoECCTest.java | |||
@@ -21,7 +21,7 @@ public class CryptoECCTest { | |||
21 | CryptoECC.PrivateKey privateKey = new CryptoECC.PrivateKey(); | 21 | CryptoECC.PrivateKey privateKey = new CryptoECC.PrivateKey(); |
22 | privateKey.d = new byte[32]; | 22 | privateKey.d = new byte[32]; |
23 | r.nextBytes(privateKey.d); | 23 | r.nextBytes(privateKey.d); |
24 | CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey); | 24 | CryptoECC.PublicSignKey publicKey = CryptoECC.computePublicKey(privateKey); |
25 | System.out.println("gen"); | 25 | System.out.println("gen"); |
26 | CryptoECC.Signature sig = CryptoECC.sign(msg, privateKey, publicKey); | 26 | CryptoECC.Signature sig = CryptoECC.sign(msg, privateKey, publicKey); |
27 | System.out.println("sign"); | 27 | System.out.println("sign"); |
@@ -44,7 +44,7 @@ public class CryptoECCTest { | |||
44 | CryptoECC.PrivateKey privateKey = new CryptoECC.PrivateKey(); | 44 | CryptoECC.PrivateKey privateKey = new CryptoECC.PrivateKey(); |
45 | privateKey.d = new byte[32]; | 45 | privateKey.d = new byte[32]; |
46 | r.nextBytes(privateKey.d); | 46 | r.nextBytes(privateKey.d); |
47 | CryptoECC.PublicKey publicKey = CryptoECC.computePublicKey(privateKey); | 47 | CryptoECC.PublicSignKey publicKey = CryptoECC.computePublicKey(privateKey); |
48 | System.out.println("gen"); | 48 | System.out.println("gen"); |
49 | CryptoECC.Signature sig = CryptoECC.sign(msg, privateKey, publicKey); | 49 | CryptoECC.Signature sig = CryptoECC.sign(msg, privateKey, publicKey); |
50 | System.out.println("sign"); | 50 | System.out.println("sign"); |
@@ -66,12 +66,12 @@ public class CryptoECCTest { | |||
66 | CryptoECC.PrivateKey privateAlice = new CryptoECC.PrivateKey(); | 66 | CryptoECC.PrivateKey privateAlice = new CryptoECC.PrivateKey(); |
67 | privateAlice.d = new byte[32]; | 67 | privateAlice.d = new byte[32]; |
68 | r.nextBytes(privateAlice.d); | 68 | r.nextBytes(privateAlice.d); |
69 | CryptoECC.PublicKey publicAlice = CryptoECC.computePublicKey(privateAlice); | 69 | CryptoECC.PublicSignKey publicAlice = CryptoECC.computePublicKey(privateAlice); |
70 | 70 | ||
71 | CryptoECC.PrivateKey privateBob = new CryptoECC.PrivateKey(); | 71 | CryptoECC.PrivateKey privateBob = new CryptoECC.PrivateKey(); |
72 | privateBob.d = new byte[32]; | 72 | privateBob.d = new byte[32]; |
73 | r.nextBytes(privateBob.d); | 73 | r.nextBytes(privateBob.d); |
74 | CryptoECC.PublicKey publicBob = CryptoECC.computePublicKey(privateBob); | 74 | CryptoECC.PublicSignKey publicBob = CryptoECC.computePublicKey(privateBob); |
75 | 75 | ||
76 | HashCode ssAlice = CryptoECC.ecdh(privateAlice, publicBob); | 76 | HashCode ssAlice = CryptoECC.ecdh(privateAlice, publicBob); |
77 | HashCode ssBob = CryptoECC.ecdh(privateBob, publicAlice); | 77 | HashCode ssBob = CryptoECC.ecdh(privateBob, publicAlice); |