manage synced SAs in IKE_SA Manager, tag them with IKE_PASSIVE state
[strongswan.git] / src / charon / plugins / ha_sync / ha_sync_ctl.c
1 /*
2 * Copyright (C) 2008 Martin Willi
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 "ha_sync_ctl.h"
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/select.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <pthread.h>
27
28 #include <processing/jobs/callback_job.h>
29
30 #define HA_SYNC_FIFO IPSEC_PIDDIR "/charon.ha"
31
32 typedef struct private_ha_sync_ctl_t private_ha_sync_ctl_t;
33
34 /**
35 * Private data of an ha_sync_ctl_t object.
36 */
37 struct private_ha_sync_ctl_t {
38
39 /**
40 * Public ha_sync_ctl_t interface.
41 */
42 ha_sync_ctl_t public;
43
44 /**
45 * Segments to control
46 */
47 ha_sync_segments_t *segments;
48
49 /**
50 * FIFO reader thread
51 */
52 callback_job_t *job;
53 };
54
55 /**
56 * FIFO dispatching function
57 */
58 static job_requeue_t dispatch_fifo(private_ha_sync_ctl_t *this)
59 {
60 int fifo, old;
61 char buf[8];
62 u_int segment;
63
64 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
65 fifo = open(HA_SYNC_FIFO, O_RDONLY);
66 pthread_setcancelstate(old, NULL);
67 if (fifo == -1)
68 {
69 DBG1(DBG_CFG, "opening HA sync fifo failed: %s", strerror(errno));
70 sleep(1);
71 return JOB_REQUEUE_FAIR;
72 }
73
74 memset(buf, 0, sizeof(buf));
75 if (read(fifo, buf, sizeof(buf)-1) > 1)
76 {
77 segment = atoi(&buf[1]);
78 if (segment)
79 {
80 switch (buf[0])
81 {
82 case '+':
83 this->segments->activate(this->segments, segment);
84 break;
85 case '-':
86 this->segments->deactivate(this->segments, segment);
87 break;
88 default:
89 break;
90 }
91 }
92 }
93 close(fifo);
94
95 return JOB_REQUEUE_DIRECT;
96 }
97
98 /**
99 * Implementation of ha_sync_ctl_t.destroy.
100 */
101 static void destroy(private_ha_sync_ctl_t *this)
102 {
103 this->job->cancel(this->job);
104 free(this);
105 }
106
107 /**
108 * See header
109 */
110 ha_sync_ctl_t *ha_sync_ctl_create(ha_sync_segments_t *segments)
111 {
112 private_ha_sync_ctl_t *this = malloc_thing(private_ha_sync_ctl_t);
113
114 this->public.destroy = (void(*)(ha_sync_ctl_t*))destroy;
115
116 if (access(HA_SYNC_FIFO, R_OK|W_OK) != 0)
117 {
118 if (mkfifo(HA_SYNC_FIFO, 600) != 0)
119 {
120 DBG1(DBG_CFG, "creating HA sync FIFO %s failed: %s",
121 HA_SYNC_FIFO, strerror(errno));
122 }
123 }
124
125 this->segments = segments;
126 this->job = callback_job_create((callback_job_cb_t)dispatch_fifo,
127 this, NULL, NULL);
128 charon->processor->queue_job(charon->processor, (job_t*)this->job);
129 return &this->public;
130 }
131