2 * Copyright (C) 2012 Martin Willi
3 * Copyright (C) 2012 revosec AG
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>.
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
16 #include "lookip_listener.h"
19 #include <utils/hashtable.h>
20 #include <threading/rwlock.h>
22 typedef struct private_lookip_listener_t private_lookip_listener_t
;
25 * Private data of an lookip_listener_t object.
27 struct private_lookip_listener_t
{
30 * Public lookip_listener_t interface.
32 lookip_listener_t
public;
40 * Hashtable with entries: host_t => entry_t
49 /** virtual IP, serves as lookup key */
51 /** peers external address */
53 /** peer (EAP-)Identity */
55 /** associated connection name */
60 * Destroy a hashtable entry
62 static void entry_destroy(entry_t
*entry
)
64 entry
->vip
->destroy(entry
->vip
);
65 entry
->other
->destroy(entry
->other
);
66 entry
->id
->destroy(entry
->id
);
72 * Hashtable hash function
74 static u_int
hash(host_t
*key
)
76 return chunk_hash(key
->get_address(key
));
80 * Hashtable equals function
82 static bool equals(host_t
*a
, host_t
*b
)
84 return a
->ip_equals(a
, b
);
88 * Add a new entry to the hashtable
90 static void add_entry(private_lookip_listener_t
*this, ike_sa_t
*ike_sa
)
92 enumerator_t
*enumerator
;
97 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, FALSE
);
98 while (enumerator
->enumerate(enumerator
, &vip
))
100 other
= ike_sa
->get_other_host(ike_sa
);
101 id
= ike_sa
->get_other_eap_id(ike_sa
);
104 .vip
= vip
->clone(vip
),
105 .other
= other
->clone(other
),
107 .name
= strdup(ike_sa
->get_name(ike_sa
)),
110 this->lock
->write_lock(this->lock
);
111 entry
= this->entries
->put(this->entries
, entry
->vip
, entry
);
112 this->lock
->unlock(this->lock
);
115 entry_destroy(entry
);
118 enumerator
->destroy(enumerator
);
122 * Remove an entry from the hashtable
124 static void remove_entry(private_lookip_listener_t
*this, ike_sa_t
*ike_sa
)
126 enumerator_t
*enumerator
;
130 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, FALSE
);
131 while (enumerator
->enumerate(enumerator
, &vip
))
133 this->lock
->write_lock(this->lock
);
134 entry
= this->entries
->remove(this->entries
, vip
);
135 this->lock
->unlock(this->lock
);
138 entry_destroy(entry
);
141 enumerator
->destroy(enumerator
);
144 METHOD(listener_t
, message_hook
, bool,
145 private_lookip_listener_t
*this, ike_sa_t
*ike_sa
,
146 message_t
*message
, bool incoming
, bool plain
)
148 if (plain
&& ike_sa
->get_state(ike_sa
) == IKE_ESTABLISHED
&&
149 !incoming
&& !message
->get_request(message
))
151 if (ike_sa
->get_version(ike_sa
) == IKEV1
&&
152 message
->get_exchange_type(message
) == TRANSACTION
)
154 add_entry(this, ike_sa
);
156 if (ike_sa
->get_version(ike_sa
) == IKEV2
&&
157 message
->get_exchange_type(message
) == IKE_AUTH
)
159 add_entry(this, ike_sa
);
165 METHOD(listener_t
, ike_updown
, bool,
166 private_lookip_listener_t
*this, ike_sa_t
*ike_sa
, bool up
)
170 remove_entry(this, ike_sa
);
175 METHOD(lookip_listener_t
, destroy
, void,
176 private_lookip_listener_t
*this)
178 this->entries
->destroy(this->entries
);
179 this->lock
->destroy(this->lock
);
186 lookip_listener_t
*lookip_listener_create()
188 private_lookip_listener_t
*this;
193 .message
= _message_hook
,
194 .ike_updown
= _ike_updown
,
198 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
199 .entries
= hashtable_create((hashtable_hash_t
)hash
,
200 (hashtable_equals_t
)equals
, 32),
203 return &this->public;