Annotation of embedaddon/strongswan/src/libcharon/plugins/ha/ha_ctl.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2015 Tobias Brunner
3: * Copyright (C) 2008 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
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>.
10: *
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
14: * for more details.
15: */
16:
17: #include "ha_ctl.h"
18:
19: #include <sys/types.h>
20: #include <sys/stat.h>
21: #include <sys/select.h>
22: #include <fcntl.h>
23: #include <unistd.h>
24: #include <errno.h>
25:
26: #include <threading/thread.h>
27: #include <processing/jobs/callback_job.h>
28:
29: #define HA_FIFO IPSEC_PIDDIR "/charon.ha"
30:
31: typedef struct private_ha_ctl_t private_ha_ctl_t;
32:
33: /**
34: * Private data of an ha_ctl_t object.
35: */
36: struct private_ha_ctl_t {
37:
38: /**
39: * Public ha_ctl_t interface.
40: */
41: ha_ctl_t public;
42:
43: /**
44: * Segments to control
45: */
46: ha_segments_t *segments;
47:
48: /**
49: * Resynchronization message cache
50: */
51: ha_cache_t *cache;
52: };
53:
54: /**
55: * Change the permissions of the control FIFO, returns TRUE on success
56: */
57: static bool change_fifo_permissions()
58: {
59: if (chown(HA_FIFO, lib->caps->get_uid(lib->caps),
60: lib->caps->get_gid(lib->caps)) != 0)
61: {
62: DBG1(DBG_CFG, "changing HA FIFO permissions failed: %s",
63: strerror(errno));
64: return FALSE;
65: }
66: return TRUE;
67: }
68:
69: /**
70: * Deletes and creates the control FIFO, returns TRUE on success
71: */
72: static bool recreate_fifo()
73: {
74: mode_t old;
75: bool success = TRUE;
76:
77: unlink(HA_FIFO);
78: old = umask(S_IRWXO);
79: if (mkfifo(HA_FIFO, S_IRUSR | S_IWUSR) != 0)
80: {
81: DBG1(DBG_CFG, "creating HA FIFO %s failed: %s", HA_FIFO,
82: strerror(errno));
83: success = FALSE;
84: }
85: umask(old);
86: return success && change_fifo_permissions();
87: }
88:
89: /**
90: * FIFO dispatching function
91: */
92: static job_requeue_t dispatch_fifo(private_ha_ctl_t *this)
93: {
94: int fifo;
95: bool oldstate;
96: char buf[8];
97: u_int segment;
98: struct stat sb;
99:
100: oldstate = thread_cancelability(TRUE);
101: fifo = open(HA_FIFO, O_RDONLY);
102: thread_cancelability(oldstate);
103: if (fifo == -1 || fstat(fifo, &sb) != 0 || !S_ISFIFO(sb.st_mode))
104: {
105: if (fifo == -1 && errno != ENOENT)
106: {
107: DBG1(DBG_CFG, "opening HA FIFO failed: %s", strerror(errno));
108: }
109: else
110: {
111: DBG1(DBG_CFG, "%s is not a FIFO, recreate it", HA_FIFO);
112: recreate_fifo();
113: }
114: if (fifo != -1)
115: {
116: close(fifo);
117: }
118: sleep(1);
119: return JOB_REQUEUE_FAIR;
120: }
121:
122: memset(buf, 0, sizeof(buf));
123: if (read(fifo, buf, sizeof(buf)-1) > 1)
124: {
125: segment = atoi(&buf[1]);
126: if (segment)
127: {
128: switch (buf[0])
129: {
130: case '+':
131: this->segments->activate(this->segments, segment, TRUE);
132: break;
133: case '-':
134: this->segments->deactivate(this->segments, segment, TRUE);
135: break;
136: case '*':
137: this->cache->resync(this->cache, segment);
138: break;
139: default:
140: break;
141: }
142: }
143: }
144: close(fifo);
145:
146: return JOB_REQUEUE_DIRECT;
147: }
148:
149: METHOD(ha_ctl_t, destroy, void,
150: private_ha_ctl_t *this)
151: {
152: unlink(HA_FIFO);
153: free(this);
154: }
155:
156: /**
157: * See header
158: */
159: ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache)
160: {
161: private_ha_ctl_t *this;
162: struct stat sb;
163:
164: INIT(this,
165: .public = {
166: .destroy = _destroy,
167: },
168: .segments = segments,
169: .cache = cache,
170: );
171:
172: if (stat(HA_FIFO, &sb) == 0)
173: {
174: if (!S_ISFIFO(sb.st_mode))
175: {
176: DBG1(DBG_CFG, "%s is not a FIFO, recreate it", HA_FIFO);
177: recreate_fifo();
178: }
179: else if (access(HA_FIFO, R_OK|W_OK) != 0)
180: {
181: DBG1(DBG_CFG, "accessing HA FIFO %s denied, recreate it", HA_FIFO);
182: recreate_fifo();
183: }
184: else
185: {
186: change_fifo_permissions();
187: }
188: }
189: else if (errno == ENOENT)
190: {
191: recreate_fifo();
192: }
193: else
194: {
195: DBG1(DBG_CFG, "accessing HA FIFO %s failed: %s", HA_FIFO,
196: strerror(errno));
197: }
198:
199: lib->processor->queue_job(lib->processor,
200: (job_t*)callback_job_create_with_prio((callback_job_cb_t)dispatch_fifo,
201: this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
202: return &this->public;
203: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>