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