Add a lookip function to register virtual IP notification listeners
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <utils/hashtable.h>
|
#include <utils/hashtable.h>
|
||||||
|
#include <utils/linked_list.h>
|
||||||
#include <threading/rwlock.h>
|
#include <threading/rwlock.h>
|
||||||
|
|
||||||
typedef struct private_lookip_listener_t private_lookip_listener_t;
|
typedef struct private_lookip_listener_t private_lookip_listener_t;
|
||||||
@@ -40,8 +41,23 @@ struct private_lookip_listener_t {
|
|||||||
* Hashtable with entries: host_t => entry_t
|
* Hashtable with entries: host_t => entry_t
|
||||||
*/
|
*/
|
||||||
hashtable_t *entries;
|
hashtable_t *entries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of registered listeners
|
||||||
|
*/
|
||||||
|
linked_list_t *listeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener entry
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** callback function */
|
||||||
|
lookip_callback_t cb;
|
||||||
|
/** user data for callback */
|
||||||
|
void *user;
|
||||||
|
} listener_entry_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashtable entry
|
* Hashtable entry
|
||||||
*/
|
*/
|
||||||
@@ -84,6 +100,34 @@ static bool equals(host_t *a, host_t *b)
|
|||||||
return a->ip_equals(a, b);
|
return a->ip_equals(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare callback that invokes up callback of all registered listeners
|
||||||
|
*/
|
||||||
|
static bool notify_up(listener_entry_t *listener, entry_t *entry)
|
||||||
|
{
|
||||||
|
if (!listener->cb(listener->user, TRUE, entry->vip, entry->other,
|
||||||
|
entry->id, entry->name))
|
||||||
|
{
|
||||||
|
free(listener);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare callback that invokes down callback of all registered listeners
|
||||||
|
*/
|
||||||
|
static bool notify_down(listener_entry_t *listener, entry_t *entry)
|
||||||
|
{
|
||||||
|
if (!listener->cb(listener->user, FALSE, entry->vip, entry->other,
|
||||||
|
entry->id, entry->name))
|
||||||
|
{
|
||||||
|
free(listener);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new entry to the hashtable
|
* Add a new entry to the hashtable
|
||||||
*/
|
*/
|
||||||
@@ -107,6 +151,10 @@ static void add_entry(private_lookip_listener_t *this, ike_sa_t *ike_sa)
|
|||||||
.name = strdup(ike_sa->get_name(ike_sa)),
|
.name = strdup(ike_sa->get_name(ike_sa)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->lock->read_lock(this->lock);
|
||||||
|
this->listeners->remove(this->listeners, entry, (void*)notify_up);
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
|
|
||||||
this->lock->write_lock(this->lock);
|
this->lock->write_lock(this->lock);
|
||||||
entry = this->entries->put(this->entries, entry->vip, entry);
|
entry = this->entries->put(this->entries, entry->vip, entry);
|
||||||
this->lock->unlock(this->lock);
|
this->lock->unlock(this->lock);
|
||||||
@@ -135,6 +183,10 @@ static void remove_entry(private_lookip_listener_t *this, ike_sa_t *ike_sa)
|
|||||||
this->lock->unlock(this->lock);
|
this->lock->unlock(this->lock);
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
|
this->lock->read_lock(this->lock);
|
||||||
|
this->listeners->remove(this->listeners, entry, (void*)notify_down);
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
|
|
||||||
entry_destroy(entry);
|
entry_destroy(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +236,7 @@ METHOD(lookip_listener_t, lookup, void,
|
|||||||
entry = this->entries->get(this->entries, vip);
|
entry = this->entries->get(this->entries, vip);
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
cb(user, entry->vip, entry->other, entry->id, entry->name);
|
cb(user, TRUE, entry->vip, entry->other, entry->id, entry->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -194,16 +246,32 @@ METHOD(lookip_listener_t, lookup, void,
|
|||||||
enumerator = this->entries->create_enumerator(this->entries);
|
enumerator = this->entries->create_enumerator(this->entries);
|
||||||
while (enumerator->enumerate(enumerator, &vip, &entry))
|
while (enumerator->enumerate(enumerator, &vip, &entry))
|
||||||
{
|
{
|
||||||
cb(user, entry->vip, entry->other, entry->id, entry->name);
|
cb(user, TRUE, entry->vip, entry->other, entry->id, entry->name);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
this->lock->unlock(this->lock);
|
this->lock->unlock(this->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(lookip_listener_t, add_listener, void,
|
||||||
|
private_lookip_listener_t *this, lookip_callback_t cb, void *user)
|
||||||
|
{
|
||||||
|
listener_entry_t *listener;
|
||||||
|
|
||||||
|
INIT(listener,
|
||||||
|
.cb = cb,
|
||||||
|
.user = user,
|
||||||
|
);
|
||||||
|
|
||||||
|
this->lock->write_lock(this->lock);
|
||||||
|
this->listeners->insert_last(this->listeners, listener);
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(lookip_listener_t, destroy, void,
|
METHOD(lookip_listener_t, destroy, void,
|
||||||
private_lookip_listener_t *this)
|
private_lookip_listener_t *this)
|
||||||
{
|
{
|
||||||
|
this->listeners->destroy_function(this->listeners, free);
|
||||||
this->entries->destroy(this->entries);
|
this->entries->destroy(this->entries);
|
||||||
this->lock->destroy(this->lock);
|
this->lock->destroy(this->lock);
|
||||||
free(this);
|
free(this);
|
||||||
@@ -223,11 +291,13 @@ lookip_listener_t *lookip_listener_create()
|
|||||||
.ike_updown = _ike_updown,
|
.ike_updown = _ike_updown,
|
||||||
},
|
},
|
||||||
.lookup = _lookup,
|
.lookup = _lookup,
|
||||||
|
.add_listener = _add_listener,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||||
.entries = hashtable_create((hashtable_hash_t)hash,
|
.entries = hashtable_create((hashtable_hash_t)hash,
|
||||||
(hashtable_equals_t)equals, 32),
|
(hashtable_equals_t)equals, 32),
|
||||||
|
.listeners = linked_list_create(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -29,14 +29,15 @@ typedef struct lookip_listener_t lookip_listener_t;
|
|||||||
* Callback function to query virtual IP entries
|
* Callback function to query virtual IP entries
|
||||||
*
|
*
|
||||||
* @param user user supplied pointer
|
* @param user user supplied pointer
|
||||||
|
* @param up TRUE if tunnels established, FALSE if closed
|
||||||
* @param vip virtual IP of remote peer
|
* @param vip virtual IP of remote peer
|
||||||
* @param other peer external IP
|
* @param other peer external IP
|
||||||
* @param id peer identity
|
* @param id peer identity
|
||||||
* @param name associated connection name
|
* @param name associated connection name
|
||||||
* @return TRUE to receive more results, FALSE to cancel
|
* @return TRUE to receive more results, FALSE to cancel
|
||||||
*/
|
*/
|
||||||
typedef bool (*lookip_callback_t)(void *user, host_t *vip, host_t *other,
|
typedef bool (*lookip_callback_t)(void *user, bool up, host_t *vip,
|
||||||
identification_t *id, char *name);
|
host_t *other, identification_t *id, char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener collecting virtual IPs.
|
* Listener collecting virtual IPs.
|
||||||
@@ -51,6 +52,9 @@ struct lookip_listener_t {
|
|||||||
/**
|
/**
|
||||||
* Perform a lookup for a given virtual IP, invoke callback for matches.
|
* Perform a lookup for a given virtual IP, invoke callback for matches.
|
||||||
*
|
*
|
||||||
|
* The "up" parameter is always TRUE when the callback is invoked using
|
||||||
|
* lookup().
|
||||||
|
*
|
||||||
* @param vip virtual IP to look up, NULL to get all entries
|
* @param vip virtual IP to look up, NULL to get all entries
|
||||||
* @param cb callback function to invoke
|
* @param cb callback function to invoke
|
||||||
* @param user user data to pass to callback function
|
* @param user user data to pass to callback function
|
||||||
@@ -58,6 +62,15 @@ struct lookip_listener_t {
|
|||||||
void (*lookup)(lookip_listener_t *this, host_t *vip,
|
void (*lookup)(lookip_listener_t *this, host_t *vip,
|
||||||
lookip_callback_t cb, void *user);
|
lookip_callback_t cb, void *user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a listener function that gets notified about virtual IP changes.
|
||||||
|
*
|
||||||
|
* @param cb callback function to invoke
|
||||||
|
* @param user user data to pass to callback function
|
||||||
|
*/
|
||||||
|
void (*add_listener)(lookip_listener_t *this,
|
||||||
|
lookip_callback_t cb, void *user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a lookip_listener_t.
|
* Destroy a lookip_listener_t.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user