diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-08-27 17:16:18 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-08-27 17:16:18 +0000 |
commit | a942ffadee0fe9fd385decdf818ad6baae8c99b3 (patch) | |
tree | d500fbdba7379631b0591a19417c7c3f3df29194 /src/main/java/org/gnunet/util/Service.java | |
parent | 6be9a1ed1b7847c795cb700e3e0bd87824fc0573 (diff) | |
download | gnunet-java-a942ffadee0fe9fd385decdf818ad6baae8c99b3.tar.gz gnunet-java-a942ffadee0fe9fd385decdf818ad6baae8c99b3.zip |
- adapted source tree structure to gradle/maven conventions
- added gradle wrapper
- fixes to adapt to GNUnet changes (new time unit, ...)
- helper process in util
- started implementing testbed
- skeleton for voting tools
- use new mq api
- implemented some more transport api
- mesh
Diffstat (limited to 'src/main/java/org/gnunet/util/Service.java')
-rw-r--r-- | src/main/java/org/gnunet/util/Service.java | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/main/java/org/gnunet/util/Service.java b/src/main/java/org/gnunet/util/Service.java new file mode 100644 index 0000000..d93e296 --- /dev/null +++ b/src/main/java/org/gnunet/util/Service.java | |||
@@ -0,0 +1,154 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2011, 2012 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 | |||
24 | import org.slf4j.Logger; | ||
25 | import org.slf4j.LoggerFactory; | ||
26 | |||
27 | import java.io.*; | ||
28 | import java.net.InetAddress; | ||
29 | import java.net.InetSocketAddress; | ||
30 | import java.net.SocketAddress; | ||
31 | import java.nio.ByteBuffer; | ||
32 | import java.nio.channels.Pipe; | ||
33 | import java.util.LinkedList; | ||
34 | |||
35 | /** | ||
36 | * Server the entry point class for every gnunet-java component providing services | ||
37 | * to other components. | ||
38 | * | ||
39 | * The configuration for the server (i.e. ports/interfaces) is loaded with the standard configuration system. | ||
40 | * | ||
41 | * Note that other processes can send signals to the service via a pipe, whose name has to be given in the | ||
42 | * environment variable GNUNET_OS_CONTROL_PIPE | ||
43 | */ | ||
44 | public abstract class Service extends Program { | ||
45 | private static final Logger logger = LoggerFactory | ||
46 | .getLogger(Service.class); | ||
47 | |||
48 | private Server s; | ||
49 | private String serviceName; | ||
50 | private RelativeTime idleTimeout; | ||
51 | private boolean requireFound; | ||
52 | |||
53 | |||
54 | private Cancelable sigpipeTask; | ||
55 | private Pipe.SourceChannel sigpipeChannel; | ||
56 | |||
57 | public Service(String serviceName, RelativeTime idleTimeout, boolean requireFound, String[] args) { | ||
58 | super(args); | ||
59 | this.serviceName = serviceName; | ||
60 | this.idleTimeout = idleTimeout; | ||
61 | this.requireFound = requireFound; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * Obtain the server used by a service. Note that the server must NOT | ||
66 | * be destroyed by the caller. | ||
67 | * | ||
68 | * @return handle to the server for this service, NULL if there is none | ||
69 | */ | ||
70 | public final Server getServer() { | ||
71 | return s; | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * Stop the service. | ||
76 | */ | ||
77 | public void stop() { | ||
78 | s.stopListening(); | ||
79 | } | ||
80 | |||
81 | public void runHook() { | ||
82 | String ip4AddrList = getConfiguration().getValueString(serviceName, "ACCEPT_FROM").orNull(); | ||
83 | String ip6AddrList = getConfiguration().getValueString(serviceName, "ACCEPT_FROM6").orNull(); | ||
84 | int port = getConfiguration().getValueNumber(serviceName, "PORT").get().intValue(); | ||
85 | |||
86 | LinkedList<SocketAddress> addrs = new LinkedList<SocketAddress>(); | ||
87 | |||
88 | if (ip4AddrList != null) { | ||
89 | for (String ip4Addr : ip4AddrList.split("[;]")) { | ||
90 | InetAddress addr = Resolver.getInetAddressFromString(ip4Addr); | ||
91 | addrs.add(new InetSocketAddress(addr, port)); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | if (ip6AddrList != null) { | ||
96 | for (String ip6Addr : ip6AddrList.split("[;]")) { | ||
97 | InetAddress addr = Resolver.getInetAddressFromString(ip6Addr); | ||
98 | addrs.add(new InetSocketAddress(addr, port)); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | s = new Server(addrs, idleTimeout, requireFound); | ||
103 | |||
104 | String pipeName = System.getenv("GNUNET_OS_CONTROL_PIPE"); | ||
105 | if (pipeName != null && !pipeName.isEmpty()) { | ||
106 | Scheduler.FilePipe p = Scheduler.openFilePipe(new File(pipeName)); | ||
107 | |||
108 | Scheduler.TaskConfiguration t = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, | ||
109 | new SigpipeTask()); | ||
110 | t.selectRead(p.getSource()); | ||
111 | sigpipeTask = t.schedule(); | ||
112 | sigpipeChannel = p.getSource(); | ||
113 | } | ||
114 | |||
115 | run(); | ||
116 | } | ||
117 | |||
118 | private class SigpipeTask implements Scheduler.Task { | ||
119 | @Override | ||
120 | public void run(Scheduler.RunContext ctx) { | ||
121 | ByteBuffer b = ByteBuffer.allocate(1); | ||
122 | int n; | ||
123 | try { | ||
124 | n = sigpipeChannel.read(b); | ||
125 | } catch (IOException e) { | ||
126 | logger.error("error reading signal pipe", e); | ||
127 | return; | ||
128 | } | ||
129 | b.flip(); | ||
130 | boolean stopped = false; | ||
131 | |||
132 | if (n == 1) { | ||
133 | byte sig = b.get(); | ||
134 | // 15=sigterm | ||
135 | if (sig == 15) { | ||
136 | logger.info("service shutting down"); | ||
137 | getServer().stopListening(); | ||
138 | stopped = true; | ||
139 | } | ||
140 | } | ||
141 | if (!stopped) { | ||
142 | Scheduler.TaskConfiguration t = new Scheduler.TaskConfiguration(RelativeTime.FOREVER, this); | ||
143 | sigpipeTask = t.schedule(); | ||
144 | } else { | ||
145 | try { | ||
146 | sigpipeChannel.close(); | ||
147 | } catch (IOException e) { | ||
148 | logger.error("could not close sigpipe channel, quitting"); | ||
149 | } | ||
150 | System.exit(2); | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | } \ No newline at end of file | ||