Fawkes API Fawkes Development Version
mod_protobuf.cpp
1
2/***************************************************************************
3 * mod_protobuf.cpp - OpenPRS protobuf communication module
4 *
5 * Created: Tue Sep 02 16:23:43 2014
6 * Copyright 2014 Tim Niemueller [www.niemueller.de]
7 ****************************************************************************/
8
9/* This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * Read the full text in the LICENSE.GPL file in the doc directory.
20 */
21
22#include "oprs_protobuf.h"
23
24#include <core/exception.h>
25#include <plugins/openprs/mod_utils.h>
26
27#include <lisp-list_f-pub.h>
28#include <oprs-array_f-pub.h>
29#include <oprs-type_f-pub.h>
30#include <oprs_f-pub.h>
31#include <slistPack_f.h>
32
33using namespace oprs_protobuf;
34
35extern "C" void finalize();
36
37#define ASSERT_PB \
38 do { \
39 if (!g_oprs_pb) { \
40 fprintf(stderr, "Error: pb-setup has not been called\n"); \
41 ACTION_FAIL(); \
42 } \
43 } while (0);
44
45#define ASSERT_B_PB \
46 do { \
47 if (!g_oprs_pb) { \
48 fprintf(stderr, "Error: pb-setup has not been called\n"); \
49 return true; \
50 } \
51 } while (0);
52
53// Global variables
54OpenPRSProtobuf *g_oprs_pb = NULL;
55
56extern "C" Term *
57action_pb_setup(TermList terms)
58{
59 int terms_len = sl_slist_length(terms);
60 if (terms_len != 1) {
61 fprintf(stderr,
62 "Error[pb-setup]: invalid number of "
63 "arguments: req 1, got %i\n",
64 terms_len);
65 ACTION_FAIL();
66 }
67
68 Term *proto_paths = (Term *)get_list_pos(terms, 1);
69 if (proto_paths->type != LISP_LIST) {
70 fprintf(stderr, "Error[pb-setup]: proto paths type is not a LISP_LIST\n");
71 ACTION_FAIL();
72 }
73
74 size_t num_paths = 0;
75 for (L_List p_l = proto_paths->u.l_list; p_l; p_l = l_cdr(p_l)) {
76 Term *t = l_car(p_l);
77 if (t->type != STRING) {
78 fprintf(stderr, "Error[pb-setup]: at least one proto path is not of type STRING\n");
79 ACTION_FAIL();
80 }
81 num_paths += 1;
82 }
83
84 std::vector<std::string> ppaths(num_paths);
85 size_t i = 0;
86 for (L_List p_l = proto_paths->u.l_list; p_l; p_l = l_cdr(p_l)) {
87 Term *t = l_car(p_l);
88 ppaths[i++] = t->u.string;
89 }
90
91 for (size_t i = 0; i < ppaths.size(); ++i) {
92 std::string::size_type pos;
93 if ((pos = ppaths[i].find("@BASEDIR@")) != std::string::npos) {
94 ppaths[i].replace(pos, 9, BASEDIR);
95 }
96 if ((pos = ppaths[i].find("@FAWKES_BASEDIR@")) != std::string::npos) {
97 ppaths[i].replace(pos, 16, FAWKES_BASEDIR);
98 }
99 if ((pos = ppaths[i].find("@RESDIR@")) != std::string::npos) {
100 ppaths[i].replace(pos, 8, RESDIR);
101 }
102 if ((pos = ppaths[i].find("@CONFDIR@")) != std::string::npos) {
103 ppaths[i].replace(pos, 9, CONFDIR);
104 }
105 if (ppaths[i][ppaths.size() - 1] != '/') {
106 ppaths[i] += "/";
107 }
108 }
109
110 delete g_oprs_pb;
111 g_oprs_pb = new OpenPRSProtobuf(ppaths);
112
113 ACTION_FINAL();
114}
115
116extern "C" Term *
117func_pb_create(TermList terms)
118{
119 ASSERT_PB;
120
121 Term *type;
122
123 ACTION_ASSERT_ARG_LENGTH("pb-create", terms, 1);
124 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-create", type, terms, 1, STRING);
125
126 try {
127 std::shared_ptr<google::protobuf::Message> *msg = g_oprs_pb->oprs_create_msg(type->u.string);
128
129 Term *res = MAKE_OBJECT(Term);
130 res->type = U_POINTER;
131 res->u.u_pointer = msg;
132 return res;
133 } catch (std::runtime_error &e) {
134 fprintf(stderr, "Cannot create message of type %s: %s", type->u.string, e.what());
135 return build_nil();
136 }
137}
138
139extern "C" Term *
140action_pb_client_connect(TermList terms)
141{
142 ASSERT_PB;
143
144 Term *host, *port;
145 ACTION_ASSERT_ARG_LENGTH("pb-client-connect", terms, 2);
146 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-client-connect", host, terms, 1, STRING);
147 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-client-connect", port, terms, 2, LONG_LONG);
148
149 if (port->u.llintval < 0 || port->u.llintval > 65535) {
150 fprintf(stderr, "Error[pb-client-connect]: invalid port %lli\n", port->u.llintval);
151 ACTION_FAIL();
152 }
153
154 return g_oprs_pb->oprs_pb_client_connect(host->u.string, port->u.llintval);
155}
156
157extern "C" Term *
158action_pb_enable_server(TermList terms)
159{
160 ASSERT_PB;
161
162 Term *port;
163 ACTION_ASSERT_ARG_LENGTH("pb-enable-server", terms, 1);
164 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-enable-server", port, terms, 1, LONG_LONG);
165
166 if (port->u.llintval < 0 || port->u.llintval > 65535) {
167 fprintf(stderr, "Error[pb-enable-server]: invalid port %lli\n", port->u.llintval);
168 ACTION_FAIL();
169 }
170
171 try {
172 g_oprs_pb->oprs_pb_enable_server(port->u.llintval);
173 ACTION_FINAL();
174 } catch (fawkes::Exception &e) {
175 fprintf(stderr, "Error[pb-enable-server]: %s\n", e.what_no_backtrace());
176 ACTION_FAIL();
177 }
178}
179
180extern "C" Term *
181action_pb_disable_server(TermList terms)
182{
183 ASSERT_PB;
184
185 ACTION_ASSERT_ARG_LENGTH("pb-disable-server", terms, 0);
186
187 try {
188 g_oprs_pb->oprs_pb_disable_server();
189 ACTION_FINAL();
190 } catch (fawkes::Exception &e) {
191 fprintf(stderr, "Error[pb-disable-server]: %s\n", e.what_no_backtrace());
192 ACTION_FAIL();
193 }
194}
195
196extern "C" Term *
197action_pb_peer_create(TermList terms)
198{
199 ASSERT_PB;
200
201 Term *host, *port;
202 ACTION_ASSERT_ARG_LENGTH("pb-peer-create", terms, 2);
203 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create", host, terms, 1, STRING);
204 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create", port, terms, 2, LONG_LONG);
205
206 if (port->u.llintval < 0 || port->u.llintval > 65535) {
207 fprintf(stderr, "Error[pb-peer-create]: invalid port %lli\n", port->u.llintval);
208 ACTION_FAIL();
209 }
210
211 return g_oprs_pb->oprs_pb_peer_create(host->u.string, port->u.llintval);
212}
213
214extern "C" Term *
215action_pb_peer_create_local(TermList terms)
216{
217 ASSERT_PB;
218
219 Term *host, *send_port, *recv_port;
220 ACTION_ASSERT_ARG_LENGTH("pb-peer-create-local", terms, 3);
221 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local", host, terms, 1, STRING);
222 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local", send_port, terms, 2, LONG_LONG);
223 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local", recv_port, terms, 3, LONG_LONG);
224
225 if (send_port->u.llintval < 0 || send_port->u.llintval > 65535) {
226 fprintf(stderr, "Error[pb-peer-create-local]: invalid send port %lli\n", send_port->u.llintval);
227 ACTION_FAIL();
228 }
229 if (recv_port->u.llintval < 0 || recv_port->u.llintval > 65535) {
230 fprintf(stderr, "Error[pb-peer-create-local]: invalid recv port %lli\n", recv_port->u.llintval);
231 ACTION_FAIL();
232 }
233
234 return g_oprs_pb->oprs_pb_peer_create_local(host->u.string,
235 send_port->u.llintval,
236 recv_port->u.llintval);
237}
238
239extern "C" Term *
240action_pb_peer_create_crypto(TermList terms)
241{
242 ASSERT_PB;
243
244 Term *host, *port, *crypto_key, *cipher;
245 ACTION_ASSERT_ARG_LENGTH("pb-peer-create-local", terms, 4);
246 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", host, terms, 1, STRING);
247 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", port, terms, 2, LONG_LONG);
248 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", crypto_key, terms, 3, STRING);
249 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-crypto", cipher, terms, 4, STRING);
250
251 if (port->u.llintval < 0 || port->u.llintval > 65535) {
252 fprintf(stderr, "Error[pb-peer-create-local]: invalid port %lli\n", port->u.llintval);
253 ACTION_FAIL();
254 }
255
256 return g_oprs_pb->oprs_pb_peer_create_crypto(host->u.string,
257 port->u.llintval,
258 crypto_key->u.string,
259 cipher->u.string);
260}
261
262extern "C" Term *
263action_pb_peer_create_local_crypto(TermList terms)
264{
265 ASSERT_PB;
266
267 Term *host, *send_port, *recv_port, *crypto_key, *cipher;
268 ACTION_ASSERT_ARG_LENGTH("pb-peer-create-local-crypto", terms, 5);
269 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", host, terms, 1, STRING);
270 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", send_port, terms, 2, LONG_LONG);
271 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", recv_port, terms, 3, LONG_LONG);
272 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", crypto_key, terms, 4, STRING);
273 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-create-local-crypto", cipher, terms, 5, STRING);
274
275 if (send_port->u.llintval < 0 || send_port->u.llintval > 65535) {
276 fprintf(stderr, "Error[pb-peer-create-local]: invalid send port %lli\n", send_port->u.llintval);
277 ACTION_FAIL();
278 }
279 if (recv_port->u.llintval < 0 || recv_port->u.llintval > 65535) {
280 fprintf(stderr, "Error[pb-peer-create-local]: invalid recv port %lli\n", recv_port->u.llintval);
281 ACTION_FAIL();
282 }
283
284 printf("Creating local peer. %s:%lli %lli %s %s\n",
285 host->u.string,
286 send_port->u.llintval,
287 recv_port->u.llintval,
288 crypto_key->u.string,
289 cipher->u.string);
290 return g_oprs_pb->oprs_pb_peer_create_local_crypto(host->u.string,
291 send_port->u.llintval,
292 recv_port->u.llintval,
293 crypto_key->u.string,
294 cipher->u.string);
295}
296
297extern "C" Term *
298action_pb_peer_setup_crypto(TermList terms)
299{
300 ASSERT_PB;
301
302 Term *peer_id, *crypto_key, *cipher;
303 ACTION_ASSERT_ARG_LENGTH("pb-peer-setup-crypto", terms, 4);
304 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-setup-crypto", peer_id, terms, 1, LONG_LONG);
305 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-setup-crypto", crypto_key, terms, 2, STRING);
306 ACTION_SET_AND_ASSERT_ARG_TYPE("pb-peer-setup-crypto", cipher, terms, 3, STRING);
307
308 try {
309 g_oprs_pb->oprs_pb_peer_setup_crypto(peer_id->u.llintval,
310 crypto_key->u.string,
311 cipher->u.string);
312 ACTION_FINAL();
313 } catch (fawkes::Exception &e) {
314 fprintf(stderr, "Error[pb-peer-setup-crypto]: %s\n", e.what_no_backtrace());
315 ACTION_FAIL();
316 }
317}
318
319extern "C" PBoolean
320pred_pb_events_pending(TermList terms)
321{
322 ASSERT_B_PB;
323
324 return g_oprs_pb->oprs_pb_events_pending();
325}
326
327extern "C" Term *
328action_pb_process(TermList terms)
329{
330 ASSERT_PB;
331
332 try {
333 g_oprs_pb->oprs_pb_process();
334 ACTION_FINAL();
335 } catch (fawkes::Exception &e) {
336 fprintf(stderr, "Error[pb-process]: %s\n", e.what_no_backtrace());
337 ACTION_FAIL();
338 }
339}
340
341#define PB_FIELD_ACCESSOR_FUNC(func_name, print_name) \
342 extern "C" Term *func_pb_##func_name(TermList terms) \
343 { \
344 ASSERT_PB; \
345 \
346 Term *msg, *field_name; \
347 ACTION_ASSERT_ARG_LENGTH(print_name, terms, 2); \
348 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
349 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, field_name, terms, 2, STRING); \
350 \
351 return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer, field_name->u.string); \
352 }
353
354#define PB_FIELD_ACCESSOR_PRED(func_name, print_name) \
355 extern "C" PBoolean pred_pb_##func_name(TermList terms) \
356 { \
357 ASSERT_B_PB; \
358 \
359 Term *msg, *field_name; \
360 ACTION_ASSERT_B_ARG_LENGTH(print_name, terms, 2); \
361 ACTION_SET_AND_ASSERT_B_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
362 ACTION_SET_AND_ASSERT_B_ARG_TYPE(print_name, field_name, terms, 2, STRING); \
363 \
364 return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer, field_name->u.string); \
365 }
366
367#define PB_MESSAGE_FUNC(func_name, print_name) \
368 extern "C" Term *func_pb_##func_name(TermList terms) \
369 { \
370 ASSERT_PB; \
371 \
372 Term *msg; \
373 ACTION_ASSERT_ARG_LENGTH(print_name, terms, 1); \
374 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
375 \
376 return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer); \
377 }
378
379#define PB_MESSAGE_ACTION(func_name, print_name) \
380 extern "C" Term *action_pb_##func_name(TermList terms) \
381 { \
382 ASSERT_PB; \
383 \
384 Term *msg; \
385 ACTION_ASSERT_ARG_LENGTH(print_name, terms, 1); \
386 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
387 \
388 return g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer); \
389 }
390
391#define PB_CLIENT_MESSAGE_ACTION(func_name, print_name) \
392 extern "C" Term *action_pb_##func_name(TermList terms) \
393 { \
394 ASSERT_PB; \
395 \
396 Term *client_id, *msg; \
397 ACTION_ASSERT_ARG_LENGTH(print_name, terms, 2); \
398 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, client_id, terms, 1, LONG_LONG); \
399 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 2, U_POINTER); \
400 \
401 try { \
402 g_oprs_pb->oprs_pb_##func_name(client_id->u.llintval, msg->u.u_pointer); \
403 ACTION_FINAL(); \
404 } catch (fawkes::Exception & e) { \
405 fprintf(stderr, "Error[%s]: %s\n", print_name, e.what_no_backtrace()); \
406 ACTION_FAIL(); \
407 } \
408 }
409
410#define PB_FIELD_SET_ACTION(func_name, print_name) \
411 extern "C" Term *action_pb_##func_name(TermList terms) \
412 { \
413 ASSERT_PB; \
414 \
415 Term *msg, *field_name, *value; \
416 ACTION_ASSERT_ARG_LENGTH(print_name, terms, 3); \
417 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, msg, terms, 1, U_POINTER); \
418 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, field_name, terms, 2, STRING); \
419 value = (Term *)get_list_pos(terms, 3); \
420 \
421 try { \
422 g_oprs_pb->oprs_pb_##func_name(msg->u.u_pointer, field_name->u.string, value); \
423 ACTION_FINAL(); \
424 } catch (fawkes::Exception & e) { \
425 fprintf(stderr, "Error[%s]: %s\n", print_name, e.what_no_backtrace()); \
426 ACTION_FAIL(); \
427 } \
428 }
429
430#define PB_CLIENT_ID_ACTION(func_name, print_name) \
431 extern "C" Term *action_pb_##func_name(TermList terms) \
432 { \
433 ASSERT_PB; \
434 \
435 Term *client_id; \
436 ACTION_ASSERT_ARG_LENGTH(print_name, terms, 1); \
437 ACTION_SET_AND_ASSERT_ARG_TYPE(print_name, client_id, terms, 1, LONG_LONG); \
438 \
439 try { \
440 g_oprs_pb->oprs_pb_##func_name(client_id->u.llintval); \
441 ACTION_FINAL(); \
442 } catch (fawkes::Exception & e) { \
443 fprintf(stderr, \
444 "Error[pb-client-connect]: failed on " \
445 "client %lli\n", \
446 client_id->u.llintval); \
447 ACTION_FAIL(); \
448 } \
449 }
450
451PB_FIELD_ACCESSOR_FUNC(field_value, "pb-field-value")
452PB_FIELD_ACCESSOR_FUNC(field_type, "pb-field-type")
453PB_FIELD_ACCESSOR_FUNC(field_label, "pb-field-label")
454PB_FIELD_ACCESSOR_FUNC(field_list, "pb-field-list")
455
456PB_FIELD_ACCESSOR_PRED(has_field, "pb-has-field")
457PB_FIELD_ACCESSOR_PRED(field_is_list, "pb-field-is-list")
458
459PB_MESSAGE_FUNC(field_names, "pb-field-names")
460PB_MESSAGE_FUNC(ref, "pb-ref")
461PB_MESSAGE_ACTION(destroy, "pb-destroy")
462PB_CLIENT_MESSAGE_ACTION(send, "pb-send")
463PB_CLIENT_MESSAGE_ACTION(broadcast, "pb-broadcast")
464
465PB_FIELD_SET_ACTION(set_field, "pb-set-field")
466PB_FIELD_SET_ACTION(add_list, "pb-add-list")
467
468PB_CLIENT_ID_ACTION(disconnect, "pb-disconnect")
469PB_CLIENT_ID_ACTION(peer_destroy, "pb-peer-destroy")
470
471/** Entry function for the OpenPRS module. */
472extern "C" void
473init()
474{
475 printf("*** LOADING mod_protobuf\n");
476 printf("Make sure your kernel calls pb-setup!\n");
477
478 make_and_declare_action("pb-setup", action_pb_setup, 1);
479 make_and_declare_action("pb-process", action_pb_process, 0);
480 make_and_declare_action("pb-destroy", action_pb_destroy, 1);
481 make_and_declare_action("pb-set-field", action_pb_set_field, 3);
482 make_and_declare_action("pb-add-list", action_pb_add_list, 3);
483 make_and_declare_action("pb-disconnect", action_pb_disconnect, 1);
484 make_and_declare_action("pb-peer-destroy", action_pb_peer_destroy, 1);
485 make_and_declare_action("pb-send", action_pb_send, 2);
486 make_and_declare_action("pb-broadcast", action_pb_broadcast, 2);
487 make_and_declare_action("pb-client-connect", action_pb_client_connect, 2);
488 make_and_declare_action("pb-enable-server", action_pb_enable_server, 1);
489 make_and_declare_action("pb-disable-server", action_pb_enable_server, 1);
490 make_and_declare_action("pb-peer-create", action_pb_peer_create, 2);
491 make_and_declare_action("pb-peer-create-local", action_pb_peer_create_local, 3);
492 make_and_declare_action("pb-peer-create-crypto", action_pb_peer_create_crypto, 4);
493 make_and_declare_action("pb-peer-create-local-crypto", action_pb_peer_create_local_crypto, 5);
494 make_and_declare_action("pb-peer-setup-crypto", action_pb_peer_setup_crypto, 3);
495
496 make_and_declare_eval_funct("pb-create", func_pb_create, 1);
497 make_and_declare_eval_funct("pb-field-names", func_pb_field_names, 1);
498 make_and_declare_eval_funct("pb-ref", func_pb_ref, 1);
499 make_and_declare_eval_funct("pb-field-value", func_pb_field_value, 2);
500 make_and_declare_eval_funct("pb-field-type", func_pb_field_type, 2);
501 make_and_declare_eval_funct("pb-field-label", func_pb_field_label, 2);
502 make_and_declare_eval_funct("pb-field-list", func_pb_field_list, 2);
503
504 make_and_declare_eval_pred("pb-has-field", pred_pb_has_field, 2, TRUE);
505 make_and_declare_eval_pred("pb-is-list", pred_pb_field_is_list, 2, TRUE);
506 make_and_declare_eval_pred("pb-events-pending", pred_pb_events_pending, 0, TRUE);
507
508 add_user_end_kernel_hook(finalize);
509}
510
511/** Finalization function for the OpenPRS module. */
512extern "C" void
513finalize()
514{
515 printf("*** DESTROYING mod_protobuf\n");
516 delete g_oprs_pb;
517 g_oprs_pb = NULL;
518}
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
OpenPRS protobuf integration class.
Definition: oprs_protobuf.h:58
Term * oprs_pb_peer_create_local_crypto(const std::string &host, int send_port, int recv_port, const std::string &crypto_key="", const std::string &cipher="")
Enable protobuf peer.
Term * oprs_pb_peer_create_local(const std::string &host, int send_port, int recv_port)
Enable protobuf peer.
Term * oprs_pb_peer_create_crypto(const std::string &host, int port, const std::string &crypto_key="", const std::string &cipher="")
Enable protobuf peer.
std::shared_ptr< google::protobuf::Message > * oprs_create_msg(std::string full_name)
Create a new message of given type.
void oprs_pb_process()
Process all pending events.
bool oprs_pb_events_pending()
Check if there are pending events.
void oprs_pb_disable_server()
Disable protobuf stream server.
void oprs_pb_enable_server(int port)
Enable protobuf stream server.
Term * oprs_pb_client_connect(std::string host, int port)
Connect as a client to the given server.
Term * oprs_pb_peer_create(const std::string &host, int port)
Enable protobuf peer.
void oprs_pb_peer_setup_crypto(long int peer_id, const std::string &crypto_key, const std::string &cipher)
Setup crypto for peer.