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>