Annotation of embedaddon/strongswan/src/libcharon/plugins/farp/farp_listener.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2019 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * Copyright (C) 2010 Martin Willi
                      6:  * Copyright (C) 2010 revosec AG
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: #include "farp_listener.h"
                     20: 
                     21: #include <collections/linked_list.h>
                     22: #include <threading/rwlock.h>
                     23: 
                     24: typedef struct private_farp_listener_t private_farp_listener_t;
                     25: 
                     26: /**
                     27:  * Private data of an farp_listener_t object.
                     28:  */
                     29: struct private_farp_listener_t {
                     30: 
                     31:        /**
                     32:         * Public farp_listener_t interface.
                     33:         */
                     34:        farp_listener_t public;
                     35: 
                     36:        /**
                     37:         * List with entry_t
                     38:         */
                     39:        linked_list_t *entries;
                     40: 
                     41:        /**
                     42:         * RWlock for IP list
                     43:         */
                     44:        rwlock_t *lock;
                     45: };
                     46: 
                     47: /**
                     48:  * Traffic selector cache entry
                     49:  */
                     50: typedef struct {
                     51:        /** list of local selectors */
                     52:        linked_list_t *local;
                     53:        /** list of remote selectors */
                     54:        linked_list_t *remote;
                     55:        /** reqid of CHILD_SA */
                     56:        uint32_t reqid;
                     57: } entry_t;
                     58: 
                     59: /**
                     60:  * Destroy a cache entry
                     61:  */
                     62: static void destroy_entry(entry_t *this)
                     63: {
                     64:        this->local->destroy_offset(this->local,
                     65:                                                                offsetof(traffic_selector_t, destroy));
                     66:        this->remote->destroy_offset(this->remote,
                     67:                                                                 offsetof(traffic_selector_t, destroy));
                     68:        free(this);
                     69: }
                     70: 
                     71: METHOD(listener_t, child_updown, bool,
                     72:        private_farp_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
                     73:        bool up)
                     74: {
                     75:        enumerator_t *enumerator;
                     76:        traffic_selector_t *ts;
                     77:        entry_t *entry;
                     78:        const chunk_t full_from = chunk_from_chars(0x00, 0x00, 0x00, 0x00),
                     79:                                  full_to   = chunk_from_chars(0xff, 0xff, 0xff, 0xff);
                     80: 
                     81:        if (up)
                     82:        {
                     83:                INIT(entry,
                     84:                        .local = linked_list_create(),
                     85:                        .remote = linked_list_create(),
                     86:                        .reqid = child_sa->get_reqid(child_sa),
                     87:                );
                     88: 
                     89:                enumerator = child_sa->create_ts_enumerator(child_sa, FALSE);
                     90:                while (enumerator->enumerate(enumerator, &ts))
                     91:                {
                     92:                        if (ts->get_type(ts) != TS_IPV4_ADDR_RANGE)
                     93:                        {
                     94:                                continue;
                     95:                        }
                     96:                        /* ignore 0.0.0.0/0 remote TS because we don't want to
                     97:                         * reply to ARP requests for locally connected subnets */
                     98:                        if (chunk_equals(ts->get_from_address(ts), full_from) &&
                     99:                                chunk_equals(ts->get_to_address(ts), full_to))
                    100:                        {
                    101:                                continue;
                    102:                        }
                    103:                        entry->remote->insert_last(entry->remote, ts->clone(ts));
                    104:                }
                    105:                enumerator->destroy(enumerator);
                    106: 
                    107:                enumerator = child_sa->create_ts_enumerator(child_sa, TRUE);
                    108:                while (enumerator->enumerate(enumerator, &ts))
                    109:                {
                    110:                        if (ts->get_type(ts) != TS_IPV4_ADDR_RANGE)
                    111:                        {
                    112:                                continue;
                    113:                        }
                    114:                        entry->local->insert_last(entry->local, ts->clone(ts));
                    115:                }
                    116:                enumerator->destroy(enumerator);
                    117: 
                    118:                if (!entry->remote->get_count(entry->remote) ||
                    119:                        !entry->local->get_count(entry->local))
                    120:                {
                    121:                        destroy_entry(entry);
                    122:                        return TRUE;
                    123:                }
                    124: 
                    125:                this->lock->write_lock(this->lock);
                    126:                this->entries->insert_last(this->entries, entry);
                    127:                this->lock->unlock(this->lock);
                    128:        }
                    129:        else
                    130:        {
                    131:                this->lock->write_lock(this->lock);
                    132:                enumerator = this->entries->create_enumerator(this->entries);
                    133:                while (enumerator->enumerate(enumerator, &entry))
                    134:                {
                    135:                        if (entry->reqid == child_sa->get_reqid(child_sa))
                    136:                        {
                    137:                                this->entries->remove_at(this->entries, enumerator);
                    138:                                destroy_entry(entry);
                    139:                                break;
                    140:                        }
                    141:                }
                    142:                enumerator->destroy(enumerator);
                    143:                this->lock->unlock(this->lock);
                    144:        }
                    145:        return TRUE;
                    146: }
                    147: 
                    148: METHOD(farp_listener_t, has_tunnel, bool,
                    149:        private_farp_listener_t *this, host_t *local, host_t *remote)
                    150: {
                    151:        enumerator_t *entries, *locals, *remotes;
                    152:        traffic_selector_t *ts;
                    153:        bool found = FALSE;
                    154:        entry_t *entry;
                    155: 
                    156:        this->lock->read_lock(this->lock);
                    157:        entries = this->entries->create_enumerator(this->entries);
                    158:        while (!found && entries->enumerate(entries, &entry))
                    159:        {
                    160:                remotes = entry->remote->create_enumerator(entry->remote);
                    161:                while (!found && remotes->enumerate(remotes, &ts))
                    162:                {
                    163:                        if (ts->includes(ts, remote))
                    164:                        {
                    165:                                locals = entry->local->create_enumerator(entry->local);
                    166:                                while (!found && locals->enumerate(locals, &ts))
                    167:                                {
                    168:                                        found = ts->includes(ts, local);
                    169:                                }
                    170:                                locals->destroy(locals);
                    171:                        }
                    172:                }
                    173:                remotes->destroy(remotes);
                    174:        }
                    175:        entries->destroy(entries);
                    176:        this->lock->unlock(this->lock);
                    177: 
                    178:        return found;
                    179: }
                    180: 
                    181: METHOD(farp_listener_t, destroy, void,
                    182:        private_farp_listener_t *this)
                    183: {
                    184:        this->entries->destroy(this->entries);
                    185:        this->lock->destroy(this->lock);
                    186:        free(this);
                    187: }
                    188: 
                    189: /**
                    190:  * See header
                    191:  */
                    192: farp_listener_t *farp_listener_create()
                    193: {
                    194:        private_farp_listener_t *this;
                    195: 
                    196:        INIT(this,
                    197:                .public = {
                    198:                        .listener = {
                    199:                                .child_updown = _child_updown,
                    200:                        },
                    201:                        .has_tunnel = _has_tunnel,
                    202:                        .destroy = _destroy,
                    203:                },
                    204:                .entries = linked_list_create(),
                    205:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                    206:        );
                    207: 
                    208:        return &this->public;
                    209: }

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