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, ¤t))
! 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>