… | |
… | |
7 | =head1 SYNOPSIS |
7 | =head1 SYNOPSIS |
8 | |
8 | |
9 | aemp command args... |
9 | aemp command args... |
10 | |
10 | |
11 | # protocol commands |
11 | # protocol commands |
12 | aemp snd <port> <arg...> # send a message |
12 | aemp snd <port> <arg...> # send a message |
13 | aemp mon <port> # wait till port is killed |
13 | aemp mon <port> # wait till port is killed |
14 | aemp rpc <port> <arg...> # send message, append reply |
14 | aemp rpc <port> <arg...> # send message, append reply |
|
|
15 | |
|
|
16 | # run a node |
|
|
17 | aemp run initialise_args... # run a node |
|
|
18 | |
|
|
19 | # node configuration: protocol endpoints |
|
|
20 | aemp setnoderef <noderef> # configure the real noderef |
|
|
21 | aemp clrnoderef # reset noderef to default |
15 | |
22 | |
16 | # node configuration: secret |
23 | # node configuration: secret |
17 | aemp gensecret # generate a random shared secret |
24 | aemp gensecret # generate a random shared secret |
18 | aemp setsecret <secret> # set the shared secret |
25 | aemp setsecret <secret> # set the shared secret |
19 | aemp clrsecret # remove the secret |
26 | aemp clrsecret # remove the secret |
20 | |
27 | |
21 | # node configuration: TLS |
28 | # node configuration: TLS |
22 | aemp setcert <file> # set a certificate (key.pem + certificate.pem) |
29 | aemp setcert <file> # set a certificate (key.pem + certificate.pem) |
23 | aemp clrcert # remove certificate |
30 | aemp clrcert # remove certificate |
24 | aemp gencert # generate a random certificate |
31 | aemp gencert # generate a random certificate |
25 | |
32 | |
26 | # node configuration |
33 | # node configuration: seed nodes for bootstrapping |
27 | aemp setseeds noderef... # set seednodes |
34 | aemp setseeds <noderef>... # set seednodes |
28 | aemp addseed noderef # add a seednode |
35 | aemp addseed <noderef> # add a seednode |
29 | aemp delseed noderef # remove seednode |
36 | aemp delseed <noderef> # remove seednode |
|
|
37 | |
|
|
38 | # node configuration: services |
|
|
39 | aemp setservices initfunc... # set service functions |
|
|
40 | aemp addservice <initfunc> # add an instance of a service |
|
|
41 | aemp delservice <initfunc> # delete one instance of a service |
30 | |
42 | |
31 | =head1 DESCRIPTION |
43 | =head1 DESCRIPTION |
32 | |
44 | |
33 | With aemp you can configure various aspects of AnyEvent::MP and it's protocol. |
45 | With aemp you can configure various aspects of AnyEvent::MP and its |
|
|
46 | protocol. |
|
|
47 | |
|
|
48 | You can also start a "default node", a node that only depends on the |
|
|
49 | static configuration. |
34 | |
50 | |
35 | =cut |
51 | =cut |
36 | |
52 | |
37 | use common::sense; |
53 | use common::sense; |
|
|
54 | |
|
|
55 | BEGIN { |
|
|
56 | if ($ARGV[0] eq "run") { |
|
|
57 | shift; |
|
|
58 | |
|
|
59 | #TODO: watchdog? how? |
|
|
60 | #require AnyEvent::Watchdog; |
|
|
61 | require AnyEvent; |
|
|
62 | require AnyEvent::MP; |
|
|
63 | AnyEvent::MP::initialise_node (@ARGV); |
|
|
64 | |
|
|
65 | AnyEvent::detect () eq "AnyEvent::Impl::E" |
|
|
66 | ? EV::loop () |
|
|
67 | : AE::cv ()->recv; |
|
|
68 | } |
|
|
69 | } |
38 | |
70 | |
39 | use Carp (); |
71 | use Carp (); |
40 | |
72 | |
41 | use AnyEvent; |
73 | use AnyEvent; |
42 | use AnyEvent::Util; |
74 | use AnyEvent::Util; |
43 | |
75 | |
|
|
76 | use AnyEvent::MP; |
44 | use AnyEvent::MP::Config; |
77 | use AnyEvent::MP::Config; |
45 | use AnyEvent::MP; |
|
|
46 | |
78 | |
47 | sub my_run_cmd { |
79 | sub my_run_cmd { |
48 | my ($cmd) = @_; |
80 | my ($cmd) = @_; |
49 | |
81 | |
50 | my $cv = &run_cmd; |
82 | my $cv = &run_cmd; |
… | |
… | |
67 | |
99 | |
68 | "$cert$key" |
100 | "$cert$key" |
69 | } |
101 | } |
70 | |
102 | |
71 | our $cfg = \%AnyEvent::MP::Config::CFG; |
103 | our $cfg = \%AnyEvent::MP::Config::CFG; |
72 | our $nodecfg = $cfg; |
104 | our $profile = $cfg; |
73 | |
105 | |
74 | sub resolve_port { |
106 | sub resolve_port { |
75 | my ($node, $port) = split /#/, $_[0], 2; |
107 | my ($node, $port) = split /#/, $_[0], 2; |
76 | |
108 | |
77 | $node = (resolve_node $node)->recv; |
109 | $node = (resolve_node $node)->recv; |
… | |
… | |
113 | |
145 | |
114 | mon $port, my $cv = AE::cv; |
146 | mon $port, my $cv = AE::cv; |
115 | print join " ", $cv->recv, "\n"; |
147 | print join " ", $cv->recv, "\n"; |
116 | }, |
148 | }, |
117 | |
149 | |
|
|
150 | setnoderef => sub { |
|
|
151 | @ARGV >= 1 |
|
|
152 | or die "shared secret missing\n"; |
|
|
153 | |
|
|
154 | $profile->{noderef} = shift @ARGV; |
|
|
155 | ++$cfg->{dirty}; |
|
|
156 | }, |
|
|
157 | clrnoderef => sub { |
|
|
158 | delete $profile->{noderef}; |
|
|
159 | ++$cfg->{dirty}; |
|
|
160 | }, |
|
|
161 | |
118 | setsecret => sub { |
162 | setsecret => sub { |
119 | @ARGV == 1 |
163 | @ARGV >= 1 |
120 | or die "shared secret missing\n"; |
164 | or die "shared secret missing\n"; |
121 | |
165 | |
122 | $nodecfg->{secret} = shift @ARGV; |
166 | $profile->{secret} = shift @ARGV; |
123 | ++$cfg->{dirty}; |
167 | ++$cfg->{dirty}; |
124 | }, |
168 | }, |
125 | gensecret => sub { |
169 | gensecret => sub { |
126 | $nodecfg->{secret} = AnyEvent::MP::Base::asciibits AnyEvent::MP::Base::nonce 64; |
170 | $profile->{secret} = AnyEvent::MP::Base::asciibits AnyEvent::MP::Base::nonce 64; |
127 | ++$cfg->{dirty}; |
171 | ++$cfg->{dirty}; |
128 | }, |
172 | }, |
129 | clrsecret => sub { |
173 | clrsecret => sub { |
130 | delete $nodecfg->{secret}; |
174 | delete $profile->{secret}; |
131 | ++$cfg->{dirty}; |
175 | ++$cfg->{dirty}; |
132 | }, |
176 | }, |
133 | |
177 | |
134 | setcert => sub { |
178 | setcert => sub { |
135 | @ARGV == 1 |
179 | @ARGV >= 1 |
136 | or die "key+certificate pem filename missing\n"; |
180 | or die "key+certificate pem filename missing\n"; |
137 | |
181 | |
138 | open my $fh, "<", $ARGV[0] |
182 | open my $fh, "<", $ARGV[0] |
139 | or die "$ARGV[0]: $!"; |
183 | or die "$ARGV[0]: $!"; |
140 | |
184 | |
141 | local $/; |
185 | local $/; |
142 | $nodecfg->{cert} = <$fh>; |
186 | $profile->{cert} = <$fh>; |
143 | ++$cfg->{dirty}; |
187 | ++$cfg->{dirty}; |
144 | }, |
188 | }, |
145 | gencert => sub { |
189 | gencert => sub { |
146 | $nodecfg->{cert} = gen_cert; |
190 | $profile->{cert} = gen_cert; |
147 | ++$cfg->{dirty}; |
191 | ++$cfg->{dirty}; |
148 | }, |
192 | }, |
149 | clrcert => sub { |
193 | clrcert => sub { |
150 | delete $nodecfg->{cert}; |
194 | delete $profile->{cert}; |
151 | ++$cfg->{dirty}; |
195 | ++$cfg->{dirty}; |
152 | }, |
196 | }, |
153 | |
197 | |
154 | setseeds => sub { |
198 | setseeds => sub { |
155 | $cfg->{seeds} = [@ARGV]; |
199 | $profile->{seeds} = [@ARGV]; |
156 | @ARGV = (); |
200 | @ARGV = (); |
157 | ++$cfg->{dirty}; |
201 | ++$cfg->{dirty}; |
158 | }, |
202 | }, |
159 | addseed => sub { |
203 | addseed => sub { |
160 | my $seed = shift @ARGV; |
204 | my $seed = shift @ARGV; |
161 | @{ $cfg->{seeds} } = grep $_ ne $seed, @{ $cfg->{seeds} }; |
205 | @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} }; |
162 | push @{ $cfg->{seeds} }, $seed; |
206 | push @{ $profile->{seeds} }, $seed; |
|
|
207 | ++$cfg->{dirty}; |
|
|
208 | }, |
|
|
209 | delseed => sub { |
|
|
210 | my $seed = shift @ARGV; |
|
|
211 | @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} }; |
|
|
212 | ++$cfg->{dirty}; |
|
|
213 | }, |
|
|
214 | |
|
|
215 | setservices => sub { |
|
|
216 | $profile->{services} = [@ARGV]; |
|
|
217 | @ARGV = (); |
163 | ++$cfg->{dirty}; |
218 | ++$cfg->{dirty}; |
164 | }, |
219 | }, |
165 | addseed => sub { |
220 | addseed => sub { |
166 | my $seed = shift @ARGV; |
221 | my $service = shift @ARGV; |
167 | @{ $cfg->{seeds} } = grep $_ ne $seed, @{ $cfg->{seeds} }; |
222 | push @{ $profile->{services} }, $service; |
|
|
223 | ++$cfg->{dirty}; |
|
|
224 | }, |
|
|
225 | delseed => sub { |
|
|
226 | my $service = shift @ARGV; |
|
|
227 | for (0 .. $#{ $profile->{services} }) { |
|
|
228 | next unless $profile->{services}[$_] eq $service; |
|
|
229 | splice @{ $profile->{services} }, $_, 1; |
|
|
230 | last; |
|
|
231 | } |
168 | ++$cfg->{dirty}; |
232 | ++$cfg->{dirty}; |
169 | }, |
233 | }, |
170 | ); |
234 | ); |
171 | |
235 | |
172 | sub docmd { |
236 | sub docmd { |