a913a0735c31e797cb95142703d823080acb269f
[strongswan.git] / src / charon / sa / connect_manager.c
1 /*
2 * Copyright (C) 2007 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * $Id$
16 */
17
18 #include "connect_manager.h"
19
20 #include <pthread.h>
21 #include <math.h>
22
23 #include <daemon.h>
24 #include <utils/linked_list.h>
25 #include <crypto/hashers/hasher.h>
26
27 #include <processing/jobs/callback_job.h>
28 #include <processing/jobs/initiate_mediation_job.h>
29 #include <encoding/payloads/endpoint_notify.h>
30
31 /* base timeout
32 * the sending interval is P2P_INTERVAL * active checklists (N)
33 * retransmission timeout is P2P_INTERVAL * N * checks in waiting state (NW) */
34 #define P2P_INTERVAL 20 /* ms */
35 /* min retransmission timeout (RTO is P2P_INTERVAL * N * checks in waiting state) */
36 #define P2P_RTO_MIN 100 /* ms */
37 /* max number of retransmissions (+ the initial check) */
38 #define P2P_MAX_RETRANS 2
39
40
41 typedef struct private_connect_manager_t private_connect_manager_t;
42
43 /**
44 * Additional private members of connect_manager_t.
45 */
46 struct private_connect_manager_t {
47 /**
48 * Public interface of connect_manager_t.
49 */
50 connect_manager_t public;
51
52 /**
53 * Lock for exclusivly accessing the manager.
54 */
55 pthread_mutex_t mutex;
56
57 /**
58 * Hasher to generate signatures
59 */
60 hasher_t *hasher;
61
62 /**
63 * Linked list with initiated mediated connections
64 */
65 linked_list_t *initiated;
66
67 /**
68 * Linked list with checklists (hash table with session ID as key would be better).
69 */
70 linked_list_t *checklists;
71 };
72
73 typedef enum check_state_t check_state_t;
74
75 enum check_state_t {
76 CHECK_NONE,
77 CHECK_WAITING,
78 CHECK_IN_PROGRESS,
79 CHECK_SUCCEEDED,
80 CHECK_FAILED
81 };
82
83 typedef struct endpoint_pair_t endpoint_pair_t;
84
85 /**
86 * An entry in the check list.
87 */
88 struct endpoint_pair_t {
89 /** pair id */
90 u_int32_t id;
91
92 /** priority */
93 u_int64_t priority;
94
95 /** local endpoint */
96 host_t *local;
97
98 /** remote endpoint */
99 host_t *remote;
100
101 /** state */
102 check_state_t state;
103
104 /** number of retransmissions */
105 u_int32_t retransmitted;
106
107 /** the generated packet */
108 packet_t *packet;
109 };
110
111 /**
112 * Destroys an endpoint pair
113 */
114 static void endpoint_pair_destroy(endpoint_pair_t *this)
115 {
116 DESTROY_IF(this->local);
117 DESTROY_IF(this->remote);
118 DESTROY_IF(this->packet);
119 free(this);
120 }
121
122 /**
123 * Creates a new entry for the list.
124 */
125 static endpoint_pair_t *endpoint_pair_create(endpoint_notify_t *initiator,
126 endpoint_notify_t *responder, bool initiator_is_local)
127 {
128 endpoint_pair_t *this = malloc_thing(endpoint_pair_t);
129
130 this->id = 0;
131
132 u_int32_t pi = initiator->get_priority(initiator);
133 u_int32_t pr = responder->get_priority(responder);
134 this->priority = pow(2, 32) * min(pi, pr) + 2 * max(pi, pr) + (pi > pr ? 1 : 0);
135
136 this->local = initiator_is_local ? initiator->get_base(initiator) : responder->get_base(responder);
137 this->local = this->local->clone(this->local);
138 this->remote = initiator_is_local ? responder->get_host(responder) : initiator->get_host(initiator);
139 this->remote = this->remote->clone(this->remote);
140
141 this->state = CHECK_WAITING;
142 this->retransmitted = 0;
143 this->packet = NULL;
144
145 return this;
146 }
147
148
149 typedef struct check_list_t check_list_t;
150
151 /**
152 * An entry in the linked list.
153 */
154 struct check_list_t {
155
156 struct {
157 /** initiator's id */
158 identification_t *id;
159
160 /** initiator's key */
161 chunk_t key;
162
163 /** initiator's endpoints */
164 linked_list_t *endpoints;
165 } initiator;
166
167 struct {
168 /** responder's id */
169 identification_t *id;
170
171 /** responder's key */
172 chunk_t key;
173
174 /** responder's endpoints */
175 linked_list_t *endpoints;
176 } responder;
177
178 /** session id */
179 chunk_t session_id;
180
181 /** list of endpoint pairs */
182 linked_list_t *pairs;
183
184 /** pairs queued for triggered checks */
185 linked_list_t *triggered;
186
187 /** state */
188 check_state_t state;
189
190 /** TRUE if this is the initiator */
191 bool is_initiator;
192
193 };
194
195 /**
196 * Destroys a checklist
197 */
198 static void check_list_destroy(check_list_t *this)
199 {
200 DESTROY_IF(this->initiator.id);
201 DESTROY_IF(this->responder.id);
202
203 chunk_free(&this->session_id);
204 chunk_free(&this->initiator.key);
205 chunk_free(&this->responder.key);
206
207 DESTROY_OFFSET_IF(this->initiator.endpoints, offsetof(endpoint_notify_t, destroy));
208 DESTROY_OFFSET_IF(this->responder.endpoints, offsetof(endpoint_notify_t, destroy));
209
210 DESTROY_FUNCTION_IF(this->pairs, (void*)endpoint_pair_destroy);
211 /* this list contains some of the same elements as contained in this->pairs */
212 DESTROY_IF(this->triggered);
213
214 free(this);
215 }
216
217 /**
218 * Creates a new checklist
219 */
220 static check_list_t *check_list_create(identification_t *initiator, identification_t *responder,
221 chunk_t session_id, chunk_t initiator_key, linked_list_t *initiator_endpoints,
222 bool is_initiator)
223 {
224 check_list_t *this = malloc_thing(check_list_t);
225
226 this->session_id = chunk_clone(session_id);
227
228 this->initiator.id = initiator->clone(initiator);
229 this->initiator.key = chunk_clone(initiator_key);
230 this->initiator.endpoints = initiator_endpoints->clone_offset(initiator_endpoints, offsetof(endpoint_notify_t, clone));
231
232 this->responder.id = responder->clone(responder);
233 this->responder.key = chunk_empty;
234 this->responder.endpoints = NULL;
235
236 this->pairs = linked_list_create();
237 this->triggered = linked_list_create();
238 this->state = CHECK_NONE;
239 this->is_initiator = is_initiator;
240
241 return this;
242 }
243
244
245 typedef struct waiting_sa_t waiting_sa_t;
246
247 /**
248 * For an initiator, the data stored about a waiting mediated sa
249 */
250 struct waiting_sa_t {
251 /** ike sa id */
252 ike_sa_id_t *ike_sa_id;
253
254 /** list of child_cfg_t */
255 linked_list_t *childs;
256 };
257
258 /**
259 * Destroys a queued mediated sa
260 */
261 static void waiting_sa_destroy(waiting_sa_t *this)
262 {
263 DESTROY_IF(this->ike_sa_id);
264 this->childs->destroy_offset(this->childs, offsetof(child_cfg_t, destroy));
265 free(this);
266 }
267
268 /**
269 * Creates a new mediated sa object
270 */
271 static waiting_sa_t *waiting_sa_create(ike_sa_id_t *ike_sa_id)
272 {
273 waiting_sa_t *this = malloc_thing(waiting_sa_t);
274
275 this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
276 this->childs = linked_list_create();
277
278 return this;
279 }
280
281 typedef struct initiated_t initiated_t;
282
283 /**
284 * For an initiator, the data stored about initiated mediation connections
285 */
286 struct initiated_t {
287 /** my id */
288 identification_t *id;
289
290 /** peer id */
291 identification_t *peer_id;
292
293 /** list of mediated sas */
294 linked_list_t *mediated;
295 };
296
297 /**
298 * Destroys a queued initiation
299 */
300 static void initiated_destroy(initiated_t *this)
301 {
302 DESTROY_IF(this->id);
303 DESTROY_IF(this->peer_id);
304 this->mediated->destroy_function(this->mediated, (void*)waiting_sa_destroy);
305 free(this);
306 }
307
308 /**
309 * Creates a queued initiation
310 */
311 static initiated_t *initiated_create(identification_t *id, identification_t *peer_id)
312 {
313 initiated_t *this = malloc_thing(initiated_t);
314
315 this->id = id->clone(id);
316 this->peer_id = peer_id->clone(peer_id);
317 this->mediated = linked_list_create();
318
319 return this;
320 }
321
322
323 typedef struct check_t check_t;
324
325 /**
326 * Data exchanged in a connectivity check
327 */
328 struct check_t {
329 /** message id */
330 u_int32_t mid;
331
332 /** source of the connectivity check */
333 host_t *src;
334
335 /** destination of the connectivity check */
336 host_t *dst;
337
338 /** session id */
339 chunk_t session_id;
340
341 /** endpoint */
342 endpoint_notify_t *endpoint;
343
344 /** raw endpoint payload (to verify the signature) */
345 chunk_t endpoint_raw;
346
347 /** cookie */
348 chunk_t cookie;
349 };
350
351 /**
352 * Destroys a connectivity check
353 */
354 static void check_destroy(check_t *this)
355 {
356 chunk_free(&this->session_id);
357 chunk_free(&this->endpoint_raw);
358 chunk_free(&this->cookie);
359 DESTROY_IF(this->endpoint);
360 free(this);
361 }
362
363 /**
364 * Creates a new connectivity check
365 */
366 static check_t *check_create()
367 {
368 check_t *this = malloc_thing(check_t);
369
370 this->session_id = chunk_empty;
371 this->cookie = chunk_empty;
372 this->endpoint_raw = chunk_empty;
373 this->endpoint = NULL;
374
375 this->mid = 0;
376
377 return this;
378 }
379
380 typedef struct sender_data_t sender_data_t;
381
382 /**
383 * Data required by the sender
384 */
385 struct sender_data_t {
386 /** connect manager */
387 private_connect_manager_t *connect_manager;
388
389 /** session id */
390 chunk_t session_id;
391 };
392
393 /**
394 * Destroys a sender data object
395 */
396 static void sender_data_destroy(sender_data_t *this)
397 {
398 chunk_free(&this->session_id);
399 free(this);
400 }
401
402 /**
403 * Creates a new sender data object
404 */
405 static sender_data_t *sender_data_create(private_connect_manager_t *connect_manager, chunk_t session_id)
406 {
407 sender_data_t *this = malloc_thing(sender_data_t);
408 this->connect_manager = connect_manager;
409 this->session_id = session_id;
410 return this;
411 }
412
413 typedef struct retransmit_data_t retransmit_data_t;
414
415 /**
416 * Data required by the retransmission job
417 */
418 struct retransmit_data_t {
419 /** connect manager */
420 private_connect_manager_t *connect_manager;
421
422 /** session id */
423 chunk_t session_id;
424
425 /** message (pair) id */
426 u_int32_t mid;
427 };
428
429 /**
430 * Destroys a retransmission data object
431 */
432 static void retransmit_data_destroy(retransmit_data_t *this)
433 {
434 chunk_free(&this->session_id);
435 free(this);
436 }
437
438 /**
439 * Creates a new retransmission data object
440 */
441 static retransmit_data_t *retransmit_data_create(private_connect_manager_t *connect_manager,
442 chunk_t session_id, u_int32_t mid)
443 {
444 retransmit_data_t *this = malloc_thing(retransmit_data_t);
445
446 this->connect_manager = connect_manager;
447 this->session_id = session_id;
448 this->mid = mid;
449
450 return this;
451 }
452
453 typedef struct initiate_data_t initiate_data_t;
454
455 /**
456 * Data required by the initiate mediated
457 */
458 struct initiate_data_t {
459 /** checklist */
460 check_list_t *checklist;
461
462 /** waiting mediated connections */
463 initiated_t *initiated;
464 };
465
466 /**
467 * Destroys a initiate data object
468 */
469 static void initiate_data_destroy(initiate_data_t *this)
470 {
471 check_list_destroy(this->checklist);
472 initiated_destroy(this->initiated);
473 free(this);
474 }
475
476 /**
477 * Creates a new initiate data object
478 */
479 static initiate_data_t *initiate_data_create(check_list_t *checklist, initiated_t *initiated)
480 {
481 initiate_data_t *this = malloc_thing(initiate_data_t);
482
483 this->checklist = checklist;
484 this->initiated = initiated;
485
486 return this;
487 }
488
489 /**
490 * Find an initiated connection by the peers' ids
491 */
492 static bool match_initiated_by_ids(initiated_t *current, identification_t *id,
493 identification_t *peer_id)
494 {
495 return id->equals(id, current->id) && peer_id->equals(peer_id, current->peer_id);
496 }
497
498 static status_t get_initiated_by_ids(private_connect_manager_t *this,
499 identification_t *id, identification_t *peer_id, initiated_t **initiated)
500 {
501 return this->initiated->find_first(this->initiated,
502 (linked_list_match_t)match_initiated_by_ids,
503 (void**)initiated, id, peer_id);
504 }
505
506 /**
507 * Removes data about initiated connections
508 */
509 static void remove_initiated(private_connect_manager_t *this, initiated_t *initiated)
510 {
511 iterator_t *iterator;
512 initiated_t *current;
513
514 iterator = this->initiated->create_iterator(this->initiated, TRUE);
515 while (iterator->iterate(iterator, (void**)&current))
516 {
517 if (current == initiated)
518 {
519 iterator->remove(iterator);
520 break;
521 }
522 }
523 iterator->destroy(iterator);
524 }
525
526 /**
527 * Finds a waiting sa
528 */
529 static bool match_waiting_sa(waiting_sa_t *current, ike_sa_id_t *ike_sa_id)
530 {
531 return ike_sa_id->equals(ike_sa_id, current->ike_sa_id);
532 }
533
534 static status_t get_waiting_sa(initiated_t *initiated, ike_sa_id_t *ike_sa_id, waiting_sa_t **waiting_sa)
535 {
536 return initiated->mediated->find_first(initiated->mediated,
537 (linked_list_match_t)match_waiting_sa,
538 (void**)waiting_sa, ike_sa_id);
539 }
540
541 /**
542 * Find the checklist with a specific session ID
543 */
544 static bool match_checklist_by_id(check_list_t *current, chunk_t *session_id)
545 {
546 return chunk_equals(*session_id, current->session_id);
547 }
548
549 static status_t get_checklist_by_id(private_connect_manager_t *this,
550 chunk_t session_id, check_list_t **check_list)
551 {
552 return this->checklists->find_first(this->checklists,
553 (linked_list_match_t)match_checklist_by_id,
554 (void**)check_list, &session_id);
555 }
556
557 /**
558 * Removes a checklist
559 */
560 static void remove_checklist(private_connect_manager_t *this, check_list_t *checklist)
561 {
562 iterator_t *iterator;
563 check_list_t *current;
564
565 iterator = this->checklists->create_iterator(this->checklists, TRUE);
566 while (iterator->iterate(iterator, (void**)&current))
567 {
568 if (current == checklist)
569 {
570 iterator->remove(iterator);
571 break;
572 }
573 }
574 iterator->destroy(iterator);
575 }
576
577 /**
578 * Checks if a list of endpoint_notify_t contains a certain host_t
579 */
580 static bool match_endpoint_by_host(endpoint_notify_t *current, host_t *host)
581 {
582 return host->equals(host, current->get_host(current));
583 }
584
585 static status_t endpoints_contain(linked_list_t *endpoints, host_t *host, endpoint_notify_t **endpoint)
586 {
587 return endpoints->find_first(endpoints,
588 (linked_list_match_t)match_endpoint_by_host,
589 (void**)endpoint, host);
590 }
591
592 /**
593 * Updates the state of the whole checklist
594 */
595 static void update_checklist_state(check_list_t *checklist)
596 {
597 iterator_t *iterator;
598 endpoint_pair_t *current;
599 bool in_progress = FALSE, succeeded = FALSE;
600
601 iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE);
602 while (iterator->iterate(iterator, (void**)&current))
603 {
604 switch(current->state)
605 {
606 case CHECK_WAITING:
607 /* at least one is still waiting -> checklist remains
608 * in waiting state */
609 iterator->destroy(iterator);
610 return;
611 case CHECK_IN_PROGRESS:
612 in_progress = TRUE;
613 break;
614 case CHECK_SUCCEEDED:
615 succeeded = TRUE;
616 break;
617 default:
618 break;
619 }
620 }
621 iterator->destroy(iterator);
622
623 if (in_progress)
624 {
625 checklist->state = CHECK_IN_PROGRESS;
626 }
627 else if (succeeded)
628 {
629 checklist->state = CHECK_SUCCEEDED;
630 }
631 else
632 {
633 checklist->state = CHECK_FAILED;
634 }
635 }
636
637 /**
638 * Inserts an endpoint pair into the list of pairs ordered by priority (high to low)
639 */
640 static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair)
641 {
642 iterator_t *iterator;
643 endpoint_pair_t *current;
644 bool inserted = FALSE;
645
646 iterator = pairs->create_iterator(pairs, TRUE);
647 while (iterator->iterate(iterator, (void**)&current))
648 {
649 if (current->priority < pair->priority)
650 {
651 iterator->insert_before(iterator, pair);
652 inserted = TRUE;
653 break;
654 }
655 }
656 iterator->destroy(iterator);
657
658 if (!inserted)
659 {
660 pairs->insert_last(pairs, pair);
661 }
662 }
663
664 /**
665 * Searches a list of endpoint_pair_t for a pair with specific host_ts
666 */
667 static bool match_pair_by_hosts(endpoint_pair_t *current, host_t *local, host_t *remote)
668 {
669 return local->equals(local, current->local) && remote->equals(remote, current->remote);
670 }
671
672 static status_t get_pair_by_hosts(linked_list_t *pairs, host_t *local, host_t *remote, endpoint_pair_t **pair)
673 {
674 return pairs->find_first(pairs,
675 (linked_list_match_t)match_pair_by_hosts,
676 (void**)pair, local, remote);
677 }
678
679 /**
680 * Searches for a pair with a specific id
681 */
682 static bool match_pair_by_id(endpoint_pair_t *current, u_int32_t *id)
683 {
684 return current->id == *id;
685 }
686
687 static status_t get_pair_by_id(check_list_t *checklist, u_int32_t id, endpoint_pair_t **pair)
688 {
689 return checklist->pairs->find_first(checklist->pairs,
690 (linked_list_match_t)match_pair_by_id,
691 (void**)pair, &id);
692 }
693
694 /**
695 * Returns the best pair of state CHECK_SUCCEEDED from a checklist.
696 */
697 static bool match_succeeded_pair(endpoint_pair_t *current)
698 {
699 return current->state == CHECK_SUCCEEDED;
700 }
701
702 static status_t get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **pair)
703 {
704 return checklist->pairs->find_first(checklist->pairs,
705 (linked_list_match_t)match_succeeded_pair,
706 (void**)pair);
707 }
708
709 /**
710 * Returns and *removes* the first triggered pair in state CHECK_WAITING.
711 */
712 static bool match_waiting_pair(endpoint_pair_t *current)
713 {
714 return current->state == CHECK_WAITING;
715 }
716
717 static status_t get_triggered_pair(check_list_t *checklist, endpoint_pair_t **pair)
718 {
719 iterator_t *iterator;
720 endpoint_pair_t *current;
721 status_t status = NOT_FOUND;
722
723 iterator = checklist->triggered->create_iterator(checklist->triggered, TRUE);
724 while (iterator->iterate(iterator, (void**)&current))
725 {
726 iterator->remove(iterator);
727
728 if (current->state == CHECK_WAITING)
729 {
730 if (pair)
731 {
732 *pair = current;
733 }
734 status = SUCCESS;
735 break;
736 }
737 }
738 iterator->destroy(iterator);
739
740 return status;
741 }
742
743 /**
744 * Prunes identical pairs with lower priority from the list
745 * Note: this function also numbers the remaining pairs serially
746 */
747 static void prune_pairs(linked_list_t *pairs)
748 {
749 iterator_t *iterator, *search;
750 endpoint_pair_t *current, *other;
751 u_int32_t id = 0;
752
753 iterator = pairs->create_iterator(pairs, TRUE);
754 search = pairs->create_iterator(pairs, TRUE);
755 while (iterator->iterate(iterator, (void**)&current))
756 {
757 current->id = ++id;
758
759 while (search->iterate(search, (void**)&other))
760 {
761 if (current == other)
762 {
763 continue;
764 }
765
766 if (current->local->equals(current->local, other->local) &&
767 current->remote->equals(current->remote, other->remote))
768 {
769 /* since the list of pairs is sorted by priority in descending
770 * order, and we iterate the list from the beginning, we are
771 * sure that the priority of 'other' is lower than that of
772 * 'current', remove it */
773 DBG1(DBG_IKE, "pruning endpoint pair %H - %H with priority %d",
774 other->local, other->remote, other->priority);
775 search->remove(search);
776 endpoint_pair_destroy(other);
777 }
778 }
779 search->reset(search);
780 }
781 search->destroy(search);
782 iterator->destroy(iterator);
783 }
784
785 /**
786 * Builds a list of endpoint pairs
787 */
788 static void build_pairs(check_list_t *checklist)
789 {
790 iterator_t *iterator_i, *iterator_r;
791 endpoint_notify_t *initiator, *responder;
792
793 iterator_i = checklist->initiator.endpoints->create_iterator(checklist->initiator.endpoints, TRUE);
794 while (iterator_i->iterate(iterator_i, (void**)&initiator))
795 {
796 iterator_r = checklist->responder.endpoints->create_iterator(checklist->responder.endpoints, TRUE);
797 while (iterator_r->iterate(iterator_r, (void**)&responder))
798 {
799 if (initiator->get_family(initiator) != responder->get_family(responder))
800 {
801 continue;
802 }
803
804 insert_pair_by_priority(checklist->pairs,
805 endpoint_pair_create(initiator, responder, checklist->is_initiator));
806 }
807 iterator_r->destroy(iterator_r);
808 }
809 iterator_i->destroy(iterator_i);
810
811 prune_pairs(checklist->pairs);
812 }
813
814 /**
815 * Processes the payloads of a connectivity check and returns the extracted data
816 */
817 static status_t process_payloads(message_t *message, check_t *check)
818 {
819 iterator_t *iterator;
820 payload_t *payload;
821
822 iterator = message->get_payload_iterator(message);
823 while (iterator->iterate(iterator, (void**)&payload))
824 {
825 if (payload->get_type(payload) != NOTIFY)
826 {
827 DBG1(DBG_IKE, "ignoring payload of type '%N' while processing "
828 "connectivity check", payload_type_names, payload->get_type(payload));
829 continue;
830 }
831
832 notify_payload_t *notify = (notify_payload_t*)payload;
833
834 switch (notify->get_notify_type(notify))
835 {
836 case P2P_ENDPOINT:
837 {
838 if (check->endpoint)
839 {
840 DBG1(DBG_IKE, "connectivity check contains multiple P2P_ENDPOINT notifies");
841 break;
842 }
843
844 endpoint_notify_t *endpoint = endpoint_notify_create_from_payload(notify);
845 if (!endpoint)
846 {
847 DBG1(DBG_IKE, "received invalid P2P_ENDPOINT notify");
848 break;
849 }
850 check->endpoint = endpoint;
851 check->endpoint_raw = chunk_clone(notify->get_notification_data(notify));
852 DBG2(DBG_IKE, "received P2P_ENDPOINT notify");
853 break;
854 }
855 case P2P_SESSIONID:
856 {
857 if (check->session_id.ptr)
858 {
859 DBG1(DBG_IKE, "connectivity check contains multiple P2P_SESSIONID notifies");
860 break;
861 }
862 check->session_id = chunk_clone(notify->get_notification_data(notify));
863 DBG2(DBG_IKE, "received P2P_SESSIONID %#B", &check->session_id);
864 break;
865 }
866 case COOKIE:
867 {
868 if (check->cookie.ptr)
869 {
870 DBG1(DBG_IKE, "connectivity check contains multiple COOKIE notifies");
871 break;
872 }
873 check->cookie = chunk_clone(notify->get_notification_data(notify));
874 DBG2(DBG_IKE, "received COOKIE %#B", &check->cookie);
875 break;
876 }
877 default:
878 break;
879 }
880 }
881 iterator->destroy(iterator);
882
883 if (!check->session_id.ptr || !check->endpoint || !check->cookie.ptr)
884 {
885 DBG1(DBG_IKE, "at least one payload was missing from the connectivity check");
886 return FAILED;
887 }
888
889 return SUCCESS;
890 }
891
892 /**
893 * Builds the signature for a connectivity check
894 */
895 static chunk_t build_signature(private_connect_manager_t *this,
896 check_list_t *checklist, check_t *check, bool outbound)
897 {
898 chunk_t mid_chunk, key_chunk, sig_chunk;
899 chunk_t sig_hash;
900
901 mid_chunk = chunk_from_thing(check->mid);
902
903 key_chunk = (checklist->is_initiator && outbound) || (!checklist->is_initiator && !outbound)
904 ? checklist->initiator.key : checklist->responder.key;
905
906 /* signature = SHA1( MID | P2P_SESSIONID | P2P_ENDPOINT | P2P_SESSIONKEY ) */
907 sig_chunk = chunk_cat("cccc", mid_chunk, check->session_id, check->endpoint_raw, key_chunk);
908 this->hasher->allocate_hash(this->hasher, sig_chunk, &sig_hash);
909 DBG3(DBG_IKE, "sig_chunk %B", &sig_chunk);
910 DBG3(DBG_IKE, "sig_hash %B", &sig_hash);
911
912 chunk_free(&sig_chunk);
913 return sig_hash;
914 }
915
916 static void queue_retransmission(private_connect_manager_t *this, chunk_t session_id, u_int32_t mid);
917 static void schedule_checks(private_connect_manager_t *this, check_list_t *checklist, u_int32_t time);
918 static void finish_checks(private_connect_manager_t *this, check_list_t *checklist);
919
920 /**
921 * This function is triggered for each sent check after a specific timeout
922 */
923 static job_requeue_t retransmit(retransmit_data_t *data)
924 {
925 private_connect_manager_t *this = data->connect_manager;
926
927 pthread_mutex_lock(&(this->mutex));
928
929 check_list_t *checklist;
930 if (get_checklist_by_id(this, data->session_id, &checklist) != SUCCESS)
931 {
932 DBG1(DBG_IKE, "checklist with id '%B' not found, can't retransmit connectivity check",
933 &data->session_id);
934 pthread_mutex_unlock(&(this->mutex));
935 return JOB_REQUEUE_NONE;
936 }
937
938 endpoint_pair_t *pair;
939 if (get_pair_by_id(checklist, data->mid, &pair) != SUCCESS)
940 {
941 DBG1(DBG_IKE, "pair with id '%d' not found, can't retransmit connectivity check",
942 data->mid);
943 goto retransmit_end;
944 }
945
946 if (pair->state != CHECK_IN_PROGRESS)
947 {
948 DBG2(DBG_IKE, "pair with id '%d' is in wrong state [%d], don't retransmit the connectivity check",
949 data->mid, pair->state);
950 goto retransmit_end;
951 }
952
953 if (++pair->retransmitted >= P2P_MAX_RETRANS)
954 {
955 DBG2(DBG_IKE, "pair with id '%d' failed after %d tries",
956 data->mid, pair->retransmitted);
957 pair->state = CHECK_FAILED;
958 goto retransmit_end;
959 }
960
961 charon->sender->send(charon->sender, pair->packet->clone(pair->packet));
962
963 queue_retransmission(this, checklist->session_id, pair->id);
964
965 retransmit_end:
966 update_checklist_state(checklist);
967
968 switch(checklist->state)
969 {
970 case CHECK_SUCCEEDED:
971 case CHECK_FAILED:
972 finish_checks(this, checklist);
973 break;
974 default:
975 break;
976 }
977
978 pthread_mutex_unlock(&(this->mutex));
979
980 /* we reschedule it manually */
981 return JOB_REQUEUE_NONE;
982 }
983
984 /**
985 * Queues a retransmission job
986 */
987 static void queue_retransmission(private_connect_manager_t *this, chunk_t session_id, u_int32_t mid)
988 {
989 retransmit_data_t *data = retransmit_data_create(this, chunk_clone(session_id), mid);
990 job_t *job = (job_t*)callback_job_create((callback_job_cb_t)retransmit, data, (callback_job_cleanup_t)retransmit_data_destroy, NULL);
991 charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, P2P_RTO_MIN);
992 }
993
994 /**
995 * Sends a check
996 */
997 static void send_check(private_connect_manager_t *this, check_list_t *checklist,
998 check_t *check, endpoint_pair_t *pair, bool request)
999 {
1000 message_t *message = message_create();
1001 message->set_message_id(message, check->mid);
1002 message->set_exchange_type(message, INFORMATIONAL);
1003 message->set_request(message, request);
1004 message->set_destination(message, check->dst->clone(check->dst));
1005 message->set_source(message, check->src->clone(check->src));
1006
1007 message->set_ike_sa_id(message, ike_sa_id_create(0, 0, request));
1008
1009 message->add_notify(message, FALSE, P2P_SESSIONID, check->session_id);
1010 DBG2(DBG_IKE, "send P2P_SESSIONID %#B", &check->session_id);
1011
1012 notify_payload_t *endpoint = check->endpoint->build_notify(check->endpoint);
1013 check->endpoint_raw = chunk_clone(endpoint->get_notification_data(endpoint));
1014 message->add_payload(message, (payload_t*)endpoint);
1015 DBG2(DBG_IKE, "send P2P_ENDPOINT notify");
1016
1017 check->cookie = build_signature(this, checklist, check, TRUE);
1018 message->add_notify(message, FALSE, COOKIE, check->cookie);
1019 DBG2(DBG_IKE, "send COOKIE %#B", &check->cookie);
1020
1021 packet_t *packet;
1022 if (message->generate(message, NULL, NULL, &packet) == SUCCESS)
1023 {
1024 charon->sender->send(charon->sender, packet->clone(packet));
1025
1026 if (request)
1027 {
1028 DESTROY_IF(pair->packet);
1029 pair->packet = packet;
1030 queue_retransmission(this, checklist->session_id, pair->id);
1031 }
1032 else
1033 {
1034 packet->destroy(packet);
1035 }
1036 }
1037 }
1038
1039 /**
1040 * Queues a triggered check
1041 */
1042 static void queue_triggered_check(check_list_t *checklist, endpoint_pair_t *pair)
1043 {
1044 pair->state = CHECK_WAITING;
1045 checklist->triggered->insert_last(checklist->triggered, pair);
1046 }
1047
1048 /**
1049 * This function is triggered for each checklist at a specific interval
1050 */
1051 static job_requeue_t sender(sender_data_t *data)
1052 {
1053 private_connect_manager_t *this = data->connect_manager;
1054
1055 pthread_mutex_lock(&(this->mutex));
1056
1057 check_list_t *checklist;
1058 if (get_checklist_by_id(this, data->session_id, &checklist) != SUCCESS)
1059 {
1060 DBG1(DBG_IKE, "checklist with id '%B' not found, can't send connectivity check",
1061 &data->session_id);
1062 pthread_mutex_unlock(&(this->mutex));
1063 return JOB_REQUEUE_NONE;
1064 }
1065
1066 endpoint_pair_t *pair;
1067 if (get_triggered_pair(checklist, &pair) != SUCCESS)
1068 {
1069 DBG1(DBG_IKE, "no triggered check queued, sending an ordinary check");
1070
1071 if (checklist->pairs->find_first(checklist->pairs,
1072 (linked_list_match_t)match_waiting_pair, (void**)&pair) != SUCCESS)
1073 {
1074 pthread_mutex_unlock(&(this->mutex));
1075 DBG1(DBG_IKE, "no pairs in waiting state, aborting");
1076 return JOB_REQUEUE_NONE;
1077 }
1078 }
1079 else
1080 {
1081 DBG1(DBG_IKE, "triggered check found");
1082 }
1083
1084 check_t *check = check_create();
1085 check->mid = pair->id;
1086 check->src = pair->local->clone(pair->local);
1087 check->dst = pair->remote->clone(pair->remote);
1088 check->session_id = chunk_clone(checklist->session_id);
1089 check->endpoint = endpoint_notify_create();
1090
1091 pair->state = CHECK_IN_PROGRESS;
1092
1093 send_check(this, checklist, check, pair, TRUE);
1094
1095 check_destroy(check);
1096
1097 /* schedule this job again */
1098 u_int32_t N = this->checklists->get_count(this->checklists);
1099 schedule_checks(this, checklist, P2P_INTERVAL * N);
1100
1101 pthread_mutex_unlock(&(this->mutex));
1102
1103 /* we reschedule it manually */
1104 return JOB_REQUEUE_NONE;
1105 }
1106
1107 /**
1108 * Schedules checks for a checklist (time in ms)
1109 */
1110 static void schedule_checks(private_connect_manager_t *this, check_list_t *checklist, u_int32_t time)
1111 {
1112 chunk_t session_id = chunk_clone(checklist->session_id);
1113 sender_data_t *data = sender_data_create(this, session_id);
1114 job_t *job = (job_t*)callback_job_create((callback_job_cb_t)sender, data, (callback_job_cleanup_t)sender_data_destroy, NULL);
1115 charon->scheduler->schedule_job(charon->scheduler, job, time);
1116 }
1117
1118 /**
1119 * Initiates waiting mediated connections
1120 */
1121 static job_requeue_t initiate_mediated(initiate_data_t *data)
1122 {
1123 check_list_t *checklist = data->checklist;
1124 initiated_t *initiated = data->initiated;
1125
1126 endpoint_pair_t *pair;
1127 if (get_best_valid_pair(checklist, &pair) == SUCCESS)
1128 {
1129 waiting_sa_t *waiting_sa;
1130 iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
1131 while (iterator->iterate(iterator, (void**)&waiting_sa))
1132 {
1133 ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa->ike_sa_id);
1134 if (sa->initiate_mediated(sa, pair->local, pair->remote, waiting_sa->childs) != SUCCESS)
1135 {
1136 SIG(IKE_UP_FAILED, "establishing the mediated connection failed");
1137 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
1138 }
1139 charon->ike_sa_manager->checkin(charon->ike_sa_manager, sa);
1140 }
1141 iterator->destroy(iterator);
1142 }
1143 else
1144 {
1145 /* this should (can?) not happen */
1146 }
1147
1148 return JOB_REQUEUE_NONE;
1149 }
1150
1151 /**
1152 * Finishes checks for a checklist
1153 */
1154 static void finish_checks(private_connect_manager_t *this, check_list_t *checklist)
1155 {
1156 if (checklist->is_initiator)
1157 {
1158 initiated_t *initiated;
1159 if (get_initiated_by_ids(this, checklist->initiator.id,
1160 checklist->responder.id, &initiated) == SUCCESS)
1161 {
1162 remove_checklist(this, checklist);
1163 remove_initiated(this, initiated);
1164
1165 initiate_data_t *data = initiate_data_create(checklist, initiated);
1166 job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiate_mediated, data, (callback_job_cleanup_t)initiate_data_destroy, NULL);
1167 charon->processor->queue_job(charon->processor, job);
1168 return;
1169 }
1170 else
1171 {
1172 DBG1(DBG_IKE, "there is no mediated connection waiting between '%D' "
1173 "and '%D'", checklist->initiator.id, checklist->responder.id);
1174 }
1175 }
1176
1177 /* remove_checklist(this, checklist);
1178 * check_list_destroy(checklist);
1179 * FIXME: we should do this ^^^ after a specific timeout on the
1180 * responder side */
1181 }
1182
1183 /**
1184 * Process the response to one of our requests
1185 */
1186 static void process_response(private_connect_manager_t *this, check_t *check,
1187 check_list_t *checklist)
1188 {
1189 endpoint_pair_t *pair;
1190 if (get_pair_by_id(checklist, check->mid, &pair) == SUCCESS)
1191 {
1192 if (pair->local->equals(pair->local, check->dst) &&
1193 pair->remote->equals(pair->remote, check->src))
1194 {
1195 DBG1(DBG_IKE, "endpoint pair '%d' is valid: '%#H' - '%#H'", pair->id,
1196 pair->local, pair->remote);
1197 pair->state = CHECK_SUCCEEDED;
1198 }
1199
1200 linked_list_t *local_endpoints = checklist->is_initiator ?
1201 checklist->initiator.endpoints : checklist->responder.endpoints;
1202
1203 endpoint_notify_t *local_endpoint;
1204 if (endpoints_contain(local_endpoints,
1205 check->endpoint->get_host(check->endpoint), &local_endpoint) != SUCCESS)
1206 {
1207 local_endpoint = endpoint_notify_create_from_host(PEER_REFLEXIVE,
1208 check->endpoint->get_host(check->endpoint), pair->local);
1209 local_endpoint->set_priority(local_endpoint, check->endpoint->get_priority(check->endpoint));
1210 local_endpoints->insert_last(local_endpoints, local_endpoint);
1211 }
1212
1213 update_checklist_state(checklist);
1214
1215 switch(checklist->state)
1216 {
1217 case CHECK_SUCCEEDED:
1218 case CHECK_FAILED:
1219 finish_checks(this, checklist);
1220 break;
1221 default:
1222 break;
1223 }
1224 }
1225 else
1226 {
1227 DBG1(DBG_IKE, "pair with id '%d' not found", check->mid);
1228 }
1229 }
1230
1231 static void process_request(private_connect_manager_t *this, check_t *check,
1232 check_list_t *checklist)
1233 {
1234 linked_list_t *remote_endpoints = checklist->is_initiator ?
1235 checklist->responder.endpoints : checklist->initiator.endpoints;
1236
1237 endpoint_notify_t *peer_reflexive, *remote_endpoint;
1238 peer_reflexive = endpoint_notify_create_from_host(PEER_REFLEXIVE, check->src, NULL);
1239 peer_reflexive->set_priority(peer_reflexive, check->endpoint->get_priority(check->endpoint));
1240
1241 if (endpoints_contain(remote_endpoints, check->src, &remote_endpoint) != SUCCESS)
1242 {
1243 remote_endpoint = peer_reflexive->clone(peer_reflexive);
1244 remote_endpoints->insert_last(remote_endpoints, remote_endpoint);
1245 }
1246
1247 endpoint_pair_t *pair;
1248 if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, &pair) == SUCCESS)
1249 {
1250 switch(pair->state)
1251 {
1252 case CHECK_IN_PROGRESS:
1253 /* prevent retransmissions */
1254 pair->retransmitted = P2P_MAX_RETRANS;
1255 /* FIXME: we should wait to the next rto to send the triggered check
1256 * fall-through */
1257 case CHECK_WAITING:
1258 case CHECK_FAILED:
1259 queue_triggered_check(checklist, pair);
1260 break;
1261 case CHECK_SUCCEEDED:
1262 default:
1263 break;
1264 }
1265 }
1266 else
1267 {
1268 endpoint_notify_t *local_endpoint = endpoint_notify_create_from_host(HOST, check->dst, NULL);
1269
1270 endpoint_notify_t *initiator = checklist->is_initiator ? local_endpoint : remote_endpoint;
1271 endpoint_notify_t *responder = checklist->is_initiator ? remote_endpoint : local_endpoint;
1272
1273 pair = endpoint_pair_create(initiator, responder, checklist->is_initiator);
1274 pair->id = checklist->pairs->get_count(checklist->pairs) + 1;
1275
1276 insert_pair_by_priority(checklist->pairs, pair);
1277
1278 queue_triggered_check(checklist, pair);
1279
1280 local_endpoint->destroy(local_endpoint);
1281 }
1282
1283
1284 check_t *response = check_create();
1285
1286 response->mid = check->mid;
1287 response->src = check->dst->clone(check->dst);
1288 response->dst = check->src->clone(check->src);
1289 response->session_id = chunk_clone(check->session_id);
1290 response->endpoint = peer_reflexive;
1291
1292 send_check(this, checklist, response, pair, FALSE);
1293
1294 check_destroy(response);
1295 }
1296
1297 /**
1298 * Implementation of connect_manager_t.process_check.
1299 */
1300 static void process_check(private_connect_manager_t *this, message_t *message)
1301 {
1302 if (message->parse_body(message, NULL, NULL) != SUCCESS)
1303 {
1304 DBG1(DBG_IKE, "%N %s with message ID %d processing failed",
1305 exchange_type_names, message->get_exchange_type(message),
1306 message->get_request(message) ? "request" : "response",
1307 message->get_message_id(message));
1308 return;
1309 }
1310
1311 check_t *check = check_create();
1312 check->mid = message->get_message_id(message);
1313 check->src = message->get_source(message);
1314 check->dst = message->get_destination(message);
1315
1316 if (process_payloads(message, check) != SUCCESS)
1317 {
1318 DBG1(DBG_IKE, "invalid connectivity check %s received",
1319 message->get_request(message) ? "request" : "response");
1320 check_destroy(check);
1321 return;
1322 }
1323
1324 pthread_mutex_lock(&(this->mutex));
1325
1326 check_list_t *checklist;
1327 if (get_checklist_by_id(this, check->session_id, &checklist) != SUCCESS)
1328 {
1329 DBG1(DBG_IKE, "checklist with id '%B' not found",
1330 &check->session_id);
1331 check_destroy(check);
1332 pthread_mutex_unlock(&(this->mutex));
1333 return;
1334 }
1335
1336 chunk_t sig = build_signature(this, checklist, check, FALSE);
1337 if (!chunk_equals(sig, check->cookie))
1338 {
1339 DBG1(DBG_IKE, "connectivity check verification failed");
1340 check_destroy(check);
1341 chunk_free(&sig);
1342 pthread_mutex_unlock(&(this->mutex));
1343 return;
1344 }
1345 chunk_free(&sig);
1346
1347 if (message->get_request(message))
1348 {
1349 process_request(this, check, checklist);
1350 }
1351 else
1352 {
1353 process_response(this, check, checklist);
1354 }
1355
1356 pthread_mutex_unlock(&(this->mutex));
1357
1358 check_destroy(check);
1359 }
1360
1361 /**
1362 * Implementation of connect_manager_t.check_and_register.
1363 */
1364 static bool check_and_register(private_connect_manager_t *this,
1365 identification_t *id, identification_t *peer_id,
1366 ike_sa_id_t *mediated_sa, child_cfg_t *child)
1367 {
1368 initiated_t *initiated;
1369 bool already_there = TRUE;
1370
1371 pthread_mutex_lock(&(this->mutex));
1372
1373 if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS)
1374 {
1375 DBG2(DBG_IKE, "registered waiting mediated connection with '%D'", peer_id);
1376 initiated = initiated_create(id, peer_id);
1377 this->initiated->insert_last(this->initiated, initiated);
1378 already_there = FALSE;
1379 }
1380
1381 waiting_sa_t *waiting_sa;
1382 if (get_waiting_sa(initiated, mediated_sa, &waiting_sa) != SUCCESS)
1383 {
1384 waiting_sa = waiting_sa_create(mediated_sa);
1385 initiated->mediated->insert_last(initiated->mediated, waiting_sa);
1386 }
1387
1388 child->get_ref(child);
1389 waiting_sa->childs->insert_last(waiting_sa->childs, child);
1390
1391 pthread_mutex_unlock(&(this->mutex));
1392
1393 return already_there;
1394 }
1395
1396 /**
1397 * Implementation of connect_manager_t.check_and_initiate.
1398 */
1399 static void check_and_initiate(private_connect_manager_t *this, ike_sa_id_t *mediation_sa,
1400 identification_t *id, identification_t *peer_id)
1401 {
1402 initiated_t *initiated;
1403
1404 pthread_mutex_lock(&(this->mutex));
1405
1406 if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS)
1407 {
1408 DBG2(DBG_IKE, "no waiting mediated connections with '%D'", peer_id);
1409 pthread_mutex_unlock(&(this->mutex));
1410 return;
1411 }
1412
1413 waiting_sa_t *waiting_sa;
1414 iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
1415 while (iterator->iterate(iterator, (void**)&waiting_sa))
1416 {
1417 job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa,
1418 waiting_sa->ike_sa_id);
1419 charon->processor->queue_job(charon->processor, job);
1420 }
1421
1422 pthread_mutex_unlock(&(this->mutex));
1423 }
1424
1425 /**
1426 * Implementation of connect_manager_t.set_initiator_data.
1427 */
1428 static status_t set_initiator_data(private_connect_manager_t *this,
1429 identification_t *initiator, identification_t *responder,
1430 chunk_t session_id, chunk_t key, linked_list_t *endpoints, bool is_initiator)
1431 {
1432 check_list_t *checklist;
1433
1434 pthread_mutex_lock(&(this->mutex));
1435
1436 if (get_checklist_by_id(this, session_id, NULL) == SUCCESS)
1437 {
1438 DBG1(DBG_IKE, "checklist with id '%B' already exists, aborting",
1439 &session_id);
1440 pthread_mutex_unlock(&(this->mutex));
1441 return FAILED;
1442 }
1443
1444 checklist = check_list_create(initiator, responder, session_id, key, endpoints, is_initiator);
1445 this->checklists->insert_last(this->checklists, checklist);
1446
1447 pthread_mutex_unlock(&(this->mutex));
1448
1449 return SUCCESS;
1450 }
1451
1452 /**
1453 * Implementation of connect_manager_t.set_responder_data.
1454 */
1455 static status_t set_responder_data(private_connect_manager_t *this,
1456 chunk_t session_id, chunk_t key, linked_list_t *endpoints)
1457 {
1458 check_list_t *checklist;
1459
1460 pthread_mutex_lock(&(this->mutex));
1461
1462 if (get_checklist_by_id(this, session_id, &checklist) != SUCCESS)
1463 {
1464 DBG1(DBG_IKE, "checklist with id '%B' not found",
1465 &session_id);
1466 pthread_mutex_unlock(&(this->mutex));
1467 return NOT_FOUND;
1468 }
1469
1470 checklist->responder.key = chunk_clone(key);
1471 checklist->responder.endpoints = endpoints->clone_offset(endpoints, offsetof(endpoint_notify_t, clone));
1472 checklist->state = CHECK_WAITING;
1473
1474 build_pairs(checklist);
1475
1476 /* send the first check immediately */
1477 schedule_checks(this, checklist, 0);
1478
1479 pthread_mutex_unlock(&(this->mutex));
1480
1481 return SUCCESS;
1482 }
1483
1484 /**
1485 * Implementation of connect_manager_t.destroy.
1486 */
1487 static void destroy(private_connect_manager_t *this)
1488 {
1489 pthread_mutex_lock(&(this->mutex));
1490
1491 this->hasher->destroy(this->hasher);
1492 this->checklists->destroy_function(this->checklists, (void*)check_list_destroy);
1493 this->initiated->destroy_function(this->initiated, (void*)initiated_destroy);
1494
1495 pthread_mutex_unlock(&(this->mutex));
1496 pthread_mutex_destroy(&(this->mutex));
1497 free(this);
1498 }
1499
1500 /*
1501 * Described in header.
1502 */
1503 connect_manager_t *connect_manager_create()
1504 {
1505 private_connect_manager_t *this = malloc_thing(private_connect_manager_t);
1506
1507 this->public.destroy = (void(*)(connect_manager_t*))destroy;
1508 this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*,child_cfg_t*))check_and_register;
1509 this->public.check_and_initiate = (void(*)(connect_manager_t*,ike_sa_id_t*,identification_t*,identification_t*))check_and_initiate;
1510 this->public.set_initiator_data = (status_t(*)(connect_manager_t*,identification_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))set_initiator_data;
1511 this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data;
1512 this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check;
1513
1514 this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1515 if (hasher == NULL)
1516 {
1517 DBG1(DBG_IKE, "unable to create connect manager, SHA1 not supported");
1518 free(this);
1519 return NULL;
1520 }
1521
1522 this->checklists = linked_list_create();
1523 this->initiated = linked_list_create();
1524
1525 pthread_mutex_init(&(this->mutex), NULL);
1526
1527 return (connect_manager_t*)this;
1528 }