Annotation of embedaddon/strongswan/src/libcharon/plugins/updown/updown_handler.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2012 Martin Willi
        !             3:  * Copyright (C) 2012 revosec AG
        !             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: 
        !            16: #include "updown_handler.h"
        !            17: 
        !            18: #include <daemon.h>
        !            19: #include <collections/linked_list.h>
        !            20: #include <threading/rwlock.h>
        !            21: 
        !            22: typedef struct private_updown_handler_t private_updown_handler_t;
        !            23: 
        !            24: /**
        !            25:  * Private data of an updown_handler_t object.
        !            26:  */
        !            27: struct private_updown_handler_t {
        !            28: 
        !            29:        /**
        !            30:         * Public updown_handler_t interface.
        !            31:         */
        !            32:        updown_handler_t public;
        !            33: 
        !            34:        /**
        !            35:         * List of connection specific attributes, as attributes_t
        !            36:         */
        !            37:        linked_list_t *attrs;
        !            38: 
        !            39:        /**
        !            40:         * rwlock to lock access to pools
        !            41:         */
        !            42:        rwlock_t *lock;
        !            43: };
        !            44: 
        !            45: /**
        !            46:  * Attributes assigned to an IKE_SA
        !            47:  */
        !            48: typedef struct {
        !            49:        /** unique IKE_SA identifier */
        !            50:        u_int id;
        !            51:        /** list of DNS attributes, as host_t */
        !            52:        linked_list_t *dns;
        !            53: } attributes_t;
        !            54: 
        !            55: /**
        !            56:  * Destroy an attributes_t entry
        !            57:  */
        !            58: static void attributes_destroy(attributes_t *this)
        !            59: {
        !            60:        this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
        !            61:        free(this);
        !            62: }
        !            63: 
        !            64: METHOD(attribute_handler_t, handle, bool,
        !            65:        private_updown_handler_t *this, ike_sa_t *ike_sa,
        !            66:        configuration_attribute_type_t type, chunk_t data)
        !            67: {
        !            68:        attributes_t *current, *attr = NULL;
        !            69:        enumerator_t *enumerator;
        !            70:        host_t *host;
        !            71: 
        !            72:        switch (type)
        !            73:        {
        !            74:                case INTERNAL_IP4_DNS:
        !            75:                        host = host_create_from_chunk(AF_INET, data, 0);
        !            76:                        break;
        !            77:                case INTERNAL_IP6_DNS:
        !            78:                        host = host_create_from_chunk(AF_INET6, data, 0);
        !            79:                        break;
        !            80:                default:
        !            81:                        return FALSE;
        !            82:        }
        !            83:        if (!host)
        !            84:        {
        !            85:                return FALSE;
        !            86:        }
        !            87: 
        !            88:        this->lock->write_lock(this->lock);
        !            89:        enumerator = this->attrs->create_enumerator(this->attrs);
        !            90:        while (enumerator->enumerate(enumerator, &current))
        !            91:        {
        !            92:                if (current->id == ike_sa->get_unique_id(ike_sa))
        !            93:                {
        !            94:                        attr = current;
        !            95:                }
        !            96:        }
        !            97:        enumerator->destroy(enumerator);
        !            98: 
        !            99:        if (!attr)
        !           100:        {
        !           101:                INIT(attr,
        !           102:                        .id = ike_sa->get_unique_id(ike_sa),
        !           103:                        .dns = linked_list_create(),
        !           104:                );
        !           105:                this->attrs->insert_last(this->attrs, attr);
        !           106:        }
        !           107:        attr->dns->insert_last(attr->dns, host);
        !           108:        this->lock->unlock(this->lock);
        !           109: 
        !           110:        return TRUE;
        !           111: }
        !           112: 
        !           113: METHOD(attribute_handler_t, release, void,
        !           114:        private_updown_handler_t *this, ike_sa_t *ike_sa,
        !           115:        configuration_attribute_type_t type, chunk_t data)
        !           116: {
        !           117:        attributes_t *attr;
        !           118:        enumerator_t *enumerator, *servers;
        !           119:        host_t *host;
        !           120:        bool found = FALSE;
        !           121:        int family;
        !           122: 
        !           123:        switch (type)
        !           124:        {
        !           125:                case INTERNAL_IP4_DNS:
        !           126:                        family = AF_INET;
        !           127:                        break;
        !           128:                case INTERNAL_IP6_DNS:
        !           129:                        family = AF_INET6;
        !           130:                        break;
        !           131:                default:
        !           132:                        return;
        !           133:        }
        !           134: 
        !           135:        this->lock->write_lock(this->lock);
        !           136:        enumerator = this->attrs->create_enumerator(this->attrs);
        !           137:        while (enumerator->enumerate(enumerator, &attr))
        !           138:        {
        !           139:                if (attr->id == ike_sa->get_unique_id(ike_sa))
        !           140:                {
        !           141:                        servers = attr->dns->create_enumerator(attr->dns);
        !           142:                        while (servers->enumerate(servers, &host))
        !           143:                        {
        !           144:                                if (host->get_family(host) == family &&
        !           145:                                        chunk_equals(data, host->get_address(host)))
        !           146:                                {
        !           147:                                        attr->dns->remove_at(attr->dns, servers);
        !           148:                                        host->destroy(host);
        !           149:                                        found = TRUE;
        !           150:                                        break;
        !           151:                                }
        !           152:                        }
        !           153:                        servers->destroy(servers);
        !           154:                        if (attr->dns->get_count(attr->dns) == 0)
        !           155:                        {
        !           156:                                this->attrs->remove_at(this->attrs, enumerator);
        !           157:                                attributes_destroy(attr);
        !           158:                                break;
        !           159:                        }
        !           160:                }
        !           161:                if (found)
        !           162:                {
        !           163:                        break;
        !           164:                }
        !           165:        }
        !           166:        enumerator->destroy(enumerator);
        !           167:        this->lock->unlock(this->lock);
        !           168: }
        !           169: 
        !           170: METHOD(updown_handler_t, create_dns_enumerator, enumerator_t*,
        !           171:        private_updown_handler_t *this, u_int id)
        !           172: {
        !           173:        attributes_t *attr;
        !           174:        enumerator_t *enumerator;
        !           175:        ike_sa_t *ike_sa;
        !           176: 
        !           177:        ike_sa = charon->bus->get_sa(charon->bus);
        !           178:        if (!ike_sa)
        !           179:        {
        !           180:                return enumerator_create_empty();
        !           181:        }
        !           182: 
        !           183:        this->lock->read_lock(this->lock);
        !           184:        enumerator = this->attrs->create_enumerator(this->attrs);
        !           185:        while (enumerator->enumerate(enumerator, &attr))
        !           186:        {
        !           187:                if (attr->id == ike_sa->get_unique_id(ike_sa))
        !           188:                {
        !           189:                        enumerator->destroy(enumerator);
        !           190:                        return enumerator_create_cleaner(
        !           191:                                                                                attr->dns->create_enumerator(attr->dns),
        !           192:                                                                                (void*)this->lock->unlock, this->lock);
        !           193:                }
        !           194:        }
        !           195:        enumerator->destroy(enumerator);
        !           196:        this->lock->unlock(this->lock);
        !           197: 
        !           198:        return enumerator_create_empty();
        !           199: }
        !           200: 
        !           201: 
        !           202: METHOD(updown_handler_t, destroy, void,
        !           203:        private_updown_handler_t *this)
        !           204: {
        !           205:        this->lock->destroy(this->lock);
        !           206:        this->attrs->destroy_function(this->attrs, (void*)attributes_destroy);
        !           207:        free(this);
        !           208: }
        !           209: 
        !           210: /**
        !           211:  * See header
        !           212:  */
        !           213: updown_handler_t *updown_handler_create()
        !           214: {
        !           215:        private_updown_handler_t *this;
        !           216: 
        !           217:        INIT(this,
        !           218:                .public = {
        !           219:                        .handler = {
        !           220:                                .handle = _handle,
        !           221:                                .release = _release,
        !           222:                                .create_attribute_enumerator = enumerator_create_empty,
        !           223:                        },
        !           224:                        .create_dns_enumerator = _create_dns_enumerator,
        !           225:                        .destroy = _destroy,
        !           226:                },
        !           227:                .attrs = linked_list_create(),
        !           228:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        !           229:        );
        !           230: 
        !           231:        return &this->public;
        !           232: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>