2 * Copyright (C) 2011-2012 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "stroke_socket.h"
20 #include <sys/types.h>
22 #include <sys/socket.h>
29 #include <threading/mutex.h>
30 #include <threading/thread.h>
31 #include <threading/condvar.h>
32 #include <utils/linked_list.h>
33 #include <processing/jobs/callback_job.h>
35 #include "stroke_config.h"
36 #include "stroke_control.h"
37 #include "stroke_cred.h"
38 #include "stroke_ca.h"
39 #include "stroke_attribute.h"
40 #include "stroke_handler.h"
41 #include "stroke_list.h"
42 #include "stroke_counter.h"
45 * To avoid clogging the thread pool with (blocking) jobs, we limit the number
46 * of concurrently handled stroke commands.
48 #define MAX_CONCURRENT_DEFAULT 4
50 typedef struct stroke_job_context_t stroke_job_context_t
;
51 typedef struct private_stroke_socket_t private_stroke_socket_t
;
54 * private data of stroke_socket
56 struct private_stroke_socket_t
{
61 stroke_socket_t
public;
64 * Unix socket to listen for strokes
69 * queued stroke commands
71 linked_list_t
*commands
;
74 * lock for command list
79 * condvar to signal the arrival or completion of commands
84 * the number of currently handled commands
89 * the maximum number of concurrently handled commands
94 * configuration backend
96 stroke_config_t
*config
;
101 stroke_attribute_t
*attribute
;
104 * attribute handler (requests only)
106 stroke_handler_t
*handler
;
109 * controller to control daemon
111 stroke_control_t
*control
;
124 * status information logging
129 * Counter values for IKE events
131 stroke_counter_t
*counter
;
135 * job context to pass to processing thread
137 struct stroke_job_context_t
{
140 * file descriptor to read from
145 * global stroke interface
147 private_stroke_socket_t
*this;
151 * Helper function which corrects the string pointers
152 * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
153 * contains RELATIVE addresses (relative to the beginning of the
154 * stroke_msg). They must be corrected if they reach our address
157 static void pop_string(stroke_msg_t
*msg
, char **string
)
164 /* check for sanity of string pointer and string */
165 if (string
< (char**)msg
||
166 string
> (char**)((char*)msg
+ sizeof(stroke_msg_t
)) ||
167 (unsigned long)*string
< (unsigned long)((char*)msg
->buffer
- (char*)msg
) ||
168 (unsigned long)*string
> msg
->length
)
170 *string
= "(invalid pointer in stroke msg)";
174 *string
= (char*)msg
+ (unsigned long)*string
;
179 * Pop the strings of a stroke_end_t struct and log them for debugging purposes
181 static void pop_end(stroke_msg_t
*msg
, const char* label
, stroke_end_t
*end
)
183 pop_string(msg
, &end
->address
);
184 pop_string(msg
, &end
->subnets
);
185 pop_string(msg
, &end
->sourceip
);
186 pop_string(msg
, &end
->dns
);
187 pop_string(msg
, &end
->auth
);
188 pop_string(msg
, &end
->auth2
);
189 pop_string(msg
, &end
->id
);
190 pop_string(msg
, &end
->id2
);
191 pop_string(msg
, &end
->rsakey
);
192 pop_string(msg
, &end
->cert
);
193 pop_string(msg
, &end
->cert2
);
194 pop_string(msg
, &end
->ca
);
195 pop_string(msg
, &end
->ca2
);
196 pop_string(msg
, &end
->groups
);
197 pop_string(msg
, &end
->groups2
);
198 pop_string(msg
, &end
->cert_policy
);
199 pop_string(msg
, &end
->updown
);
201 DBG2(DBG_CFG
, " %s=%s", label
, end
->address
);
202 DBG2(DBG_CFG
, " %ssubnet=%s", label
, end
->subnets
);
203 DBG2(DBG_CFG
, " %ssourceip=%s", label
, end
->sourceip
);
204 DBG2(DBG_CFG
, " %sdns=%s", label
, end
->dns
);
205 DBG2(DBG_CFG
, " %sauth=%s", label
, end
->auth
);
206 DBG2(DBG_CFG
, " %sauth2=%s", label
, end
->auth2
);
207 DBG2(DBG_CFG
, " %sid=%s", label
, end
->id
);
208 DBG2(DBG_CFG
, " %sid2=%s", label
, end
->id2
);
209 DBG2(DBG_CFG
, " %srsakey=%s", label
, end
->rsakey
);
210 DBG2(DBG_CFG
, " %scert=%s", label
, end
->cert
);
211 DBG2(DBG_CFG
, " %scert2=%s", label
, end
->cert2
);
212 DBG2(DBG_CFG
, " %sca=%s", label
, end
->ca
);
213 DBG2(DBG_CFG
, " %sca2=%s", label
, end
->ca2
);
214 DBG2(DBG_CFG
, " %sgroups=%s", label
, end
->groups
);
215 DBG2(DBG_CFG
, " %sgroups2=%s", label
, end
->groups2
);
216 DBG2(DBG_CFG
, " %supdown=%s", label
, end
->updown
);
220 * Add a connection to the configuration list
222 static void stroke_add_conn(private_stroke_socket_t
*this, stroke_msg_t
*msg
)
224 pop_string(msg
, &msg
->add_conn
.name
);
225 DBG1(DBG_CFG
, "received stroke: add connection '%s'", msg
->add_conn
.name
);
227 DBG2(DBG_CFG
, "conn %s", msg
->add_conn
.name
);
228 pop_end(msg
, "left", &msg
->add_conn
.me
);
229 pop_end(msg
, "right", &msg
->add_conn
.other
);
230 pop_string(msg
, &msg
->add_conn
.eap_identity
);
231 pop_string(msg
, &msg
->add_conn
.aaa_identity
);
232 pop_string(msg
, &msg
->add_conn
.xauth_identity
);
233 pop_string(msg
, &msg
->add_conn
.algorithms
.ike
);
234 pop_string(msg
, &msg
->add_conn
.algorithms
.esp
);
235 pop_string(msg
, &msg
->add_conn
.ikeme
.mediated_by
);
236 pop_string(msg
, &msg
->add_conn
.ikeme
.peerid
);
237 DBG2(DBG_CFG
, " eap_identity=%s", msg
->add_conn
.eap_identity
);
238 DBG2(DBG_CFG
, " aaa_identity=%s", msg
->add_conn
.aaa_identity
);
239 DBG2(DBG_CFG
, " xauth_identity=%s", msg
->add_conn
.xauth_identity
);
240 DBG2(DBG_CFG
, " ike=%s", msg
->add_conn
.algorithms
.ike
);
241 DBG2(DBG_CFG
, " esp=%s", msg
->add_conn
.algorithms
.esp
);
242 DBG2(DBG_CFG
, " dpddelay=%d", msg
->add_conn
.dpd
.delay
);
243 DBG2(DBG_CFG
, " dpdtimeout=%d", msg
->add_conn
.dpd
.timeout
);
244 DBG2(DBG_CFG
, " dpdaction=%d", msg
->add_conn
.dpd
.action
);
245 DBG2(DBG_CFG
, " closeaction=%d", msg
->add_conn
.close_action
);
246 DBG2(DBG_CFG
, " mediation=%s", msg
->add_conn
.ikeme
.mediation ?
"yes" : "no");
247 DBG2(DBG_CFG
, " mediated_by=%s", msg
->add_conn
.ikeme
.mediated_by
);
248 DBG2(DBG_CFG
, " me_peerid=%s", msg
->add_conn
.ikeme
.peerid
);
249 DBG2(DBG_CFG
, " keyexchange=ikev%u", msg
->add_conn
.version
);
251 this->config
->add(this->config
, msg
);
252 this->attribute
->add_dns(this->attribute
, msg
);
253 this->handler
->add_attributes(this->handler
, msg
);
257 * Delete a connection from the list
259 static void stroke_del_conn(private_stroke_socket_t
*this, stroke_msg_t
*msg
)
261 pop_string(msg
, &msg
->del_conn
.name
);
262 DBG1(DBG_CFG
, "received stroke: delete connection '%s'", msg
->del_conn
.name
);
264 this->config
->del(this->config
, msg
);
265 this->attribute
->del_dns(this->attribute
, msg
);
266 this->handler
->del_attributes(this->handler
, msg
);
270 * initiate a connection by name
272 static void stroke_initiate(private_stroke_socket_t
*this, stroke_msg_t
*msg
, FILE *out
)
274 pop_string(msg
, &msg
->initiate
.name
);
275 DBG1(DBG_CFG
, "received stroke: initiate '%s'", msg
->initiate
.name
);
277 this->control
->initiate(this->control
, msg
, out
);
281 * terminate a connection by name
283 static void stroke_terminate(private_stroke_socket_t
*this, stroke_msg_t
*msg
, FILE *out
)
285 pop_string(msg
, &msg
->terminate
.name
);
286 DBG1(DBG_CFG
, "received stroke: terminate '%s'", msg
->terminate
.name
);
288 this->control
->terminate(this->control
, msg
, out
);
292 * terminate a connection by peers virtual IP
294 static void stroke_terminate_srcip(private_stroke_socket_t
*this,
295 stroke_msg_t
*msg
, FILE *out
)
297 pop_string(msg
, &msg
->terminate_srcip
.start
);
298 pop_string(msg
, &msg
->terminate_srcip
.end
);
299 DBG1(DBG_CFG
, "received stroke: terminate-srcip %s-%s",
300 msg
->terminate_srcip
.start
, msg
->terminate_srcip
.end
);
302 this->control
->terminate_srcip(this->control
, msg
, out
);
306 * rekey a connection by name/id
308 static void stroke_rekey(private_stroke_socket_t
*this, stroke_msg_t
*msg
, FILE *out
)
310 pop_string(msg
, &msg
->terminate
.name
);
311 DBG1(DBG_CFG
, "received stroke: rekey '%s'", msg
->rekey
.name
);
313 this->control
->rekey(this->control
, msg
, out
);
317 * route a policy (install SPD entries)
319 static void stroke_route(private_stroke_socket_t
*this, stroke_msg_t
*msg
, FILE *out
)
321 pop_string(msg
, &msg
->route
.name
);
322 DBG1(DBG_CFG
, "received stroke: route '%s'", msg
->route
.name
);
324 this->control
->route(this->control
, msg
, out
);
330 static void stroke_unroute(private_stroke_socket_t
*this, stroke_msg_t
*msg
, FILE *out
)
332 pop_string(msg
, &msg
->terminate
.name
);
333 DBG1(DBG_CFG
, "received stroke: unroute '%s'", msg
->route
.name
);
335 this->control
->unroute(this->control
, msg
, out
);
339 * Add a ca information record to the cainfo list
341 static void stroke_add_ca(private_stroke_socket_t
*this,
342 stroke_msg_t
*msg
, FILE *out
)
344 pop_string(msg
, &msg
->add_ca
.name
);
345 DBG1(DBG_CFG
, "received stroke: add ca '%s'", msg
->add_ca
.name
);
347 pop_string(msg
, &msg
->add_ca
.cacert
);
348 pop_string(msg
, &msg
->add_ca
.crluri
);
349 pop_string(msg
, &msg
->add_ca
.crluri2
);
350 pop_string(msg
, &msg
->add_ca
.ocspuri
);
351 pop_string(msg
, &msg
->add_ca
.ocspuri2
);
352 pop_string(msg
, &msg
->add_ca
.certuribase
);
353 DBG2(DBG_CFG
, "ca %s", msg
->add_ca
.name
);
354 DBG2(DBG_CFG
, " cacert=%s", msg
->add_ca
.cacert
);
355 DBG2(DBG_CFG
, " crluri=%s", msg
->add_ca
.crluri
);
356 DBG2(DBG_CFG
, " crluri2=%s", msg
->add_ca
.crluri2
);
357 DBG2(DBG_CFG
, " ocspuri=%s", msg
->add_ca
.ocspuri
);
358 DBG2(DBG_CFG
, " ocspuri2=%s", msg
->add_ca
.ocspuri2
);
359 DBG2(DBG_CFG
, " certuribase=%s", msg
->add_ca
.certuribase
);
361 this->ca
->add(this->ca
, msg
);
365 * Delete a ca information record from the cainfo list
367 static void stroke_del_ca(private_stroke_socket_t
*this,
368 stroke_msg_t
*msg
, FILE *out
)
370 pop_string(msg
, &msg
->del_ca
.name
);
371 DBG1(DBG_CFG
, "received stroke: delete ca '%s'", msg
->del_ca
.name
);
373 this->ca
->del(this->ca
, msg
);
378 * show status of daemon
380 static void stroke_status(private_stroke_socket_t
*this,
381 stroke_msg_t
*msg
, FILE *out
, bool all
, bool wait
)
383 pop_string(msg
, &(msg
->status
.name
));
385 this->list
->status(this->list
, msg
, out
, all
, wait
);
389 * list various information
391 static void stroke_list(private_stroke_socket_t
*this, stroke_msg_t
*msg
, FILE *out
)
393 if (msg
->list
.flags
& LIST_CAINFOS
)
395 this->ca
->list(this->ca
, msg
, out
);
397 this->list
->list(this->list
, msg
, out
);
401 * reread various information
403 static void stroke_reread(private_stroke_socket_t
*this,
404 stroke_msg_t
*msg
, FILE *out
)
406 this->cred
->reread(this->cred
, msg
, out
);
410 * purge various information
412 static void stroke_purge(private_stroke_socket_t
*this,
413 stroke_msg_t
*msg
, FILE *out
)
415 if (msg
->purge
.flags
& PURGE_OCSP
)
417 lib
->credmgr
->flush_cache(lib
->credmgr
, CERT_X509_OCSP_RESPONSE
);
419 if (msg
->purge
.flags
& PURGE_CRLS
)
421 lib
->credmgr
->flush_cache(lib
->credmgr
, CERT_X509_CRL
);
423 if (msg
->purge
.flags
& PURGE_CERTS
)
425 lib
->credmgr
->flush_cache(lib
->credmgr
, CERT_X509
);
427 if (msg
->purge
.flags
& PURGE_IKE
)
429 this->control
->purge_ike(this->control
, msg
, out
);
434 * Export in-memory credentials
436 static void stroke_export(private_stroke_socket_t
*this,
437 stroke_msg_t
*msg
, FILE *out
)
439 pop_string(msg
, &msg
->export
.selector
);
441 if (msg
->export
.flags
& EXPORT_X509
)
443 enumerator_t
*enumerator
;
444 identification_t
*id
;
448 id
= identification_create_from_string(msg
->export
.selector
);
449 enumerator
= lib
->credmgr
->create_cert_enumerator(lib
->credmgr
,
450 CERT_X509
, KEY_ANY
, id
, FALSE
);
451 while (enumerator
->enumerate(enumerator
, &cert
))
453 if (cert
->get_encoding(cert
, CERT_PEM
, &encoded
))
455 fprintf(out
, "%.*s", (int)encoded
.len
, encoded
.ptr
);
459 enumerator
->destroy(enumerator
);
467 static void stroke_leases(private_stroke_socket_t
*this,
468 stroke_msg_t
*msg
, FILE *out
)
470 pop_string(msg
, &msg
->leases
.pool
);
471 pop_string(msg
, &msg
->leases
.address
);
473 this->list
->leases(this->list
, msg
, out
);
479 static void stroke_memusage(private_stroke_socket_t
*this,
480 stroke_msg_t
*msg
, FILE *out
)
482 if (lib
->leak_detective
)
484 lib
->leak_detective
->usage(lib
->leak_detective
, out
);
489 * Set username and password for a connection
491 static void stroke_user_creds(private_stroke_socket_t
*this,
492 stroke_msg_t
*msg
, FILE *out
)
494 pop_string(msg
, &msg
->user_creds
.name
);
495 pop_string(msg
, &msg
->user_creds
.username
);
496 pop_string(msg
, &msg
->user_creds
.password
);
498 DBG1(DBG_CFG
, "received stroke: user-creds '%s'", msg
->user_creds
.name
);
500 this->config
->set_user_credentials(this->config
, msg
, out
);
504 * set the verbosity debug output
506 static void stroke_loglevel(private_stroke_socket_t
*this,
507 stroke_msg_t
*msg
, FILE *out
)
511 pop_string(msg
, &(msg
->loglevel
.type
));
512 DBG1(DBG_CFG
, "received stroke: loglevel %d for %s",
513 msg
->loglevel
.level
, msg
->loglevel
.type
);
515 group
= enum_from_name(debug_names
, msg
->loglevel
.type
);
518 fprintf(out
, "invalid type (%s)!\n", msg
->loglevel
.type
);
521 charon
->set_level(charon
, group
, msg
->loglevel
.level
);
525 * set various config options
527 static void stroke_config(private_stroke_socket_t
*this,
528 stroke_msg_t
*msg
, FILE *out
)
530 this->cred
->cachecrl(this->cred
, msg
->config
.cachecrl
);
534 * destroy a job context
536 static void stroke_job_context_destroy(stroke_job_context_t
*this)
546 * called to signal the completion of a command
548 static inline job_requeue_t
job_processed(private_stroke_socket_t
*this)
550 this->mutex
->lock(this->mutex
);
552 this->condvar
->signal(this->condvar
);
553 this->mutex
->unlock(this->mutex
);
554 return JOB_REQUEUE_NONE
;
558 * process a stroke request from the socket pointed by "fd"
560 static job_requeue_t
process(stroke_job_context_t
*ctx
)
563 u_int16_t msg_length
;
566 private_stroke_socket_t
*this = ctx
->this;
567 int strokefd
= ctx
->fd
;
569 /* peek the length */
570 bytes_read
= recv(strokefd
, &msg_length
, sizeof(msg_length
), MSG_PEEK
);
571 if (bytes_read
!= sizeof(msg_length
))
573 DBG1(DBG_CFG
, "reading length of stroke message failed: %s",
575 return job_processed(this);
579 msg
= alloca(msg_length
);
580 bytes_read
= recv(strokefd
, msg
, msg_length
, 0);
581 if (bytes_read
!= msg_length
)
583 DBG1(DBG_CFG
, "reading stroke message failed: %s", strerror(errno
));
584 return job_processed(this);
587 out
= fdopen(strokefd
, "w+");
590 DBG1(DBG_CFG
, "opening stroke output channel failed: %s", strerror(errno
));
591 return job_processed(this);
594 DBG3(DBG_CFG
, "stroke message %b", (void*)msg
, msg_length
);
599 stroke_initiate(this, msg
, out
);
602 stroke_route(this, msg
, out
);
605 stroke_unroute(this, msg
, out
);
608 stroke_terminate(this, msg
, out
);
610 case STR_TERMINATE_SRCIP
:
611 stroke_terminate_srcip(this, msg
, out
);
614 stroke_rekey(this, msg
, out
);
617 stroke_status(this, msg
, out
, FALSE
, TRUE
);
620 stroke_status(this, msg
, out
, TRUE
, TRUE
);
622 case STR_STATUS_ALL_NOBLK
:
623 stroke_status(this, msg
, out
, TRUE
, FALSE
);
626 stroke_add_conn(this, msg
);
629 stroke_del_conn(this, msg
);
632 stroke_add_ca(this, msg
, out
);
635 stroke_del_ca(this, msg
, out
);
638 stroke_loglevel(this, msg
, out
);
641 stroke_config(this, msg
, out
);
644 stroke_list(this, msg
, out
);
647 stroke_reread(this, msg
, out
);
650 stroke_purge(this, msg
, out
);
653 stroke_export(this, msg
, out
);
656 stroke_leases(this, msg
, out
);
659 stroke_memusage(this, msg
, out
);
662 stroke_user_creds(this, msg
, out
);
665 DBG1(DBG_CFG
, "received unknown stroke");
669 /* fclose() closes underlying FD */
671 return job_processed(this);
675 * Handle queued stroke commands
677 static job_requeue_t
handle(private_stroke_socket_t
*this)
679 stroke_job_context_t
*ctx
;
683 this->mutex
->lock(this->mutex
);
684 thread_cleanup_push((thread_cleanup_t
)this->mutex
->unlock
, this->mutex
);
685 oldstate
= thread_cancelability(TRUE
);
686 while (this->commands
->get_count(this->commands
) == 0 ||
687 this->handling
>= this->max_concurrent
)
689 this->condvar
->wait(this->condvar
, this->mutex
);
691 thread_cancelability(oldstate
);
692 this->commands
->remove_first(this->commands
, (void**)&ctx
);
694 thread_cleanup_pop(TRUE
);
695 job
= callback_job_create_with_prio((callback_job_cb_t
)process
, ctx
,
696 (void*)stroke_job_context_destroy
, NULL
, JOB_PRIO_HIGH
);
697 lib
->processor
->queue_job(lib
->processor
, (job_t
*)job
);
698 return JOB_REQUEUE_DIRECT
;
702 * Accept stroke commands and queue them to be handled
704 static job_requeue_t
receive(private_stroke_socket_t
*this)
706 struct sockaddr_un strokeaddr
;
707 int strokeaddrlen
= sizeof(strokeaddr
);
710 stroke_job_context_t
*ctx
;
712 oldstate
= thread_cancelability(TRUE
);
713 strokefd
= accept(this->socket
, (struct sockaddr
*)&strokeaddr
, &strokeaddrlen
);
714 thread_cancelability(oldstate
);
718 DBG1(DBG_CFG
, "accepting stroke connection failed: %s", strerror(errno
));
719 return JOB_REQUEUE_FAIR
;
726 this->mutex
->lock(this->mutex
);
727 this->commands
->insert_last(this->commands
, ctx
);
728 this->condvar
->signal(this->condvar
);
729 this->mutex
->unlock(this->mutex
);
731 return JOB_REQUEUE_FAIR
;
735 * initialize and open stroke socket
737 static bool open_socket(private_stroke_socket_t
*this)
739 struct sockaddr_un socket_addr
;
742 socket_addr
.sun_family
= AF_UNIX
;
743 strcpy(socket_addr
.sun_path
, STROKE_SOCKET
);
745 /* set up unix socket */
746 this->socket
= socket(AF_UNIX
, SOCK_STREAM
, 0);
747 if (this->socket
== -1)
749 DBG1(DBG_CFG
, "could not create stroke socket");
753 unlink(socket_addr
.sun_path
);
754 old
= umask(~(S_IRWXU
| S_IRWXG
));
755 if (bind(this->socket
, (struct sockaddr
*)&socket_addr
, sizeof(socket_addr
)) < 0)
757 DBG1(DBG_CFG
, "could not bind stroke socket: %s", strerror(errno
));
762 if (chown(socket_addr
.sun_path
, charon
->caps
->get_uid(charon
->caps
),
763 charon
->caps
->get_gid(charon
->caps
)) != 0)
765 DBG1(DBG_CFG
, "changing stroke socket permissions failed: %s",
769 if (listen(this->socket
, 10) < 0)
771 DBG1(DBG_CFG
, "could not listen on stroke socket: %s", strerror(errno
));
773 unlink(socket_addr
.sun_path
);
779 METHOD(stroke_socket_t
, destroy
, void,
780 private_stroke_socket_t
*this)
782 this->commands
->destroy_function(this->commands
, (void*)stroke_job_context_destroy
);
783 this->condvar
->destroy(this->condvar
);
784 this->mutex
->destroy(this->mutex
);
785 lib
->credmgr
->remove_set(lib
->credmgr
, &this->ca
->set
);
786 lib
->credmgr
->remove_set(lib
->credmgr
, &this->cred
->set
);
787 charon
->backends
->remove_backend(charon
->backends
, &this->config
->backend
);
788 hydra
->attributes
->remove_provider(hydra
->attributes
, &this->attribute
->provider
);
789 hydra
->attributes
->remove_handler(hydra
->attributes
, &this->handler
->handler
);
790 charon
->bus
->remove_listener(charon
->bus
, &this->counter
->listener
);
791 this->cred
->destroy(this->cred
);
792 this->ca
->destroy(this->ca
);
793 this->config
->destroy(this->config
);
794 this->attribute
->destroy(this->attribute
);
795 this->handler
->destroy(this->handler
);
796 this->control
->destroy(this->control
);
797 this->list
->destroy(this->list
);
798 this->counter
->destroy(this->counter
);
805 stroke_socket_t
*stroke_socket_create()
807 private_stroke_socket_t
*this;
815 if (!open_socket(this))
821 this->cred
= stroke_cred_create();
822 this->attribute
= stroke_attribute_create();
823 this->handler
= stroke_handler_create();
824 this->ca
= stroke_ca_create(this->cred
);
825 this->config
= stroke_config_create(this->ca
, this->cred
, this->attribute
);
826 this->control
= stroke_control_create();
827 this->list
= stroke_list_create(this->attribute
);
828 this->counter
= stroke_counter_create();
830 this->mutex
= mutex_create(MUTEX_TYPE_DEFAULT
);
831 this->condvar
= condvar_create(CONDVAR_TYPE_DEFAULT
);
832 this->commands
= linked_list_create();
833 this->max_concurrent
= lib
->settings
->get_int(lib
->settings
,
834 "%s.plugins.stroke.max_concurrent", MAX_CONCURRENT_DEFAULT
,
837 lib
->credmgr
->add_set(lib
->credmgr
, &this->ca
->set
);
838 lib
->credmgr
->add_set(lib
->credmgr
, &this->cred
->set
);
839 charon
->backends
->add_backend(charon
->backends
, &this->config
->backend
);
840 hydra
->attributes
->add_provider(hydra
->attributes
, &this->attribute
->provider
);
841 hydra
->attributes
->add_handler(hydra
->attributes
, &this->handler
->handler
);
842 charon
->bus
->add_listener(charon
->bus
, &this->counter
->listener
);
844 lib
->processor
->queue_job(lib
->processor
,
845 (job_t
*)callback_job_create_with_prio((callback_job_cb_t
)receive
, this,
846 NULL
, (callback_job_cancel_t
)return_false
, JOB_PRIO_CRITICAL
));
848 lib
->processor
->queue_job(lib
->processor
,
849 (job_t
*)callback_job_create_with_prio((callback_job_cb_t
)handle
, this,
850 NULL
, (callback_job_cancel_t
)return_false
, JOB_PRIO_CRITICAL
));
852 return &this->public;