Annotation of embedaddon/strongswan/src/libcharon/plugins/ha/ha_ctl.c, revision 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>