duplicheck: Remove confusing plugin

This plugin was developed for a customer who had very specific
requirements.  It never did anything useful for regular users and
usually caused confusing errors if they enabled it by mistake.  So
just remove it.
This commit is contained in:
Tobias Brunner
2026-07-24 15:20:24 +02:00
parent 67327e9074
commit 8b2e60b62b
15 changed files with 1 additions and 944 deletions
-1
View File
@@ -41,7 +41,6 @@ plugins = \
plugins/dhcp.opt \
plugins/dnscert.opt \
plugins/drbg.opt \
plugins/duplicheck.opt \
plugins/eap-aka.opt \
plugins/eap-aka-3gpp.opt \
plugins/eap-aka-3gpp2.opt \
-5
View File
@@ -1,5 +0,0 @@
charon.plugins.duplicheck.enable = yes
Enable duplicheck plugin (if loaded).
charon.plugins.duplicheck.socket = unix://${piddir}/charon.dck
Socket provided by the duplicheck plugin.
-4
View File
@@ -267,7 +267,6 @@ ARG_ENABL_SET([certexpire], [enable CSV export of expiration dates of used c
ARG_ENABL_SET([connmark], [enable connmark plugin using conntrack based marks to select return path SA.])
ARG_ENABL_SET([counters], [enable plugin that collects several performance counters.])
ARG_ENABL_SET([forecast], [enable forecast plugin forwarding broadcast/multicast messages.])
ARG_ENABL_SET([duplicheck], [advanced duplicate checking plugin using liveness checks.])
ARG_ENABL_SET([error-notify], [enable error notification plugin.])
ARG_ENABL_SET([farp], [enable ARP faking plugin that responds to ARP requests to peers virtual IP])
ARG_ENABL_SET([ha], [enable high availability cluster plugin.])
@@ -1614,7 +1613,6 @@ ADD_PLUGIN([error-notify], [c charon])
ADD_PLUGIN([certexpire], [c charon])
ADD_PLUGIN([systime-fix], [c charon])
ADD_PLUGIN([led], [c charon])
ADD_PLUGIN([duplicheck], [c charon])
ADD_PLUGIN([coupling], [c charon])
ADD_PLUGIN([radattr], [c charon])
ADD_PLUGIN([addrblock], [c charon])
@@ -1730,7 +1728,6 @@ AM_CONDITIONAL(USE_ERROR_NOTIFY, test x$error_notify = xtrue)
AM_CONDITIONAL(USE_CERTEXPIRE, test x$certexpire = xtrue)
AM_CONDITIONAL(USE_SYSTIME_FIX, test x$systime_fix = xtrue)
AM_CONDITIONAL(USE_LED, test x$led = xtrue)
AM_CONDITIONAL(USE_DUPLICHECK, test x$duplicheck = xtrue)
AM_CONDITIONAL(USE_COUPLING, test x$coupling = xtrue)
AM_CONDITIONAL(USE_RADATTR, test x$radattr = xtrue)
AM_CONDITIONAL(USE_EAP_SIM, test x$eap_sim = xtrue)
@@ -2078,7 +2075,6 @@ AC_CONFIG_FILES([
src/libcharon/plugins/certexpire/Makefile
src/libcharon/plugins/systime_fix/Makefile
src/libcharon/plugins/led/Makefile
src/libcharon/plugins/duplicheck/Makefile
src/libcharon/plugins/coupling/Makefile
src/libcharon/plugins/radattr/Makefile
src/libcharon/plugins/osx_attr/Makefile
+1 -1
View File
@@ -311,7 +311,7 @@ aikgen|pki)
# fall through
;;
attest|conftest|dumm|irdumm|pool|pt-tls-client|stroke|\
duplicheck|error-notify|imv_policy_manager|load-tester|lookip|whitelist|\
error-notify|imv_policy_manager|load-tester|lookip|whitelist|\
_updown|_imv_policy)
# fall through
;;
-7
View File
@@ -621,13 +621,6 @@ if MONOLITHIC
endif
endif
if USE_DUPLICHECK
SUBDIRS += plugins/duplicheck
if MONOLITHIC
libcharon_la_LIBADD += plugins/duplicheck/libstrongswan-duplicheck.la
endif
endif
if USE_COUPLING
SUBDIRS += plugins/coupling
if MONOLITHIC
@@ -1 +0,0 @@
duplicheck
@@ -1,23 +0,0 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libcharon \
-DIPSEC_PIDDIR=\"${piddir}\"
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-duplicheck.la
else
plugin_LTLIBRARIES = libstrongswan-duplicheck.la
endif
libstrongswan_duplicheck_la_SOURCES = duplicheck_plugin.h duplicheck_plugin.c \
duplicheck_listener.h duplicheck_listener.c \
duplicheck_notify.h duplicheck_notify.c \
duplicheck_msg.h
libstrongswan_duplicheck_la_LDFLAGS = -module -avoid-version
ipsec_PROGRAMS = duplicheck
duplicheck_SOURCES = duplicheck.c
@@ -1,117 +0,0 @@
/*
* Copyright (C) 2011 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "duplicheck_msg.h"
/**
* Connect to the daemon, return FD
*/
static int make_connection()
{
union {
struct sockaddr_un un;
struct sockaddr_in in;
struct sockaddr sa;
} addr;
int fd, len;
if (getenv("TCP_PORT"))
{
addr.in.sin_family = AF_INET;
addr.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.in.sin_port = htons(atoi(getenv("TCP_PORT")));
len = sizeof(addr.in);
}
else
{
addr.un.sun_family = AF_UNIX;
strcpy(addr.un.sun_path, DUPLICHECK_SOCKET);
len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.un.sun_path);
}
fd = socket(addr.sa.sa_family, SOCK_STREAM, 0);
if (fd < 0)
{
fprintf(stderr, "opening socket failed: %s\n", strerror(errno));
return -1;
}
if (connect(fd, &addr.sa, len) < 0)
{
fprintf(stderr, "connecting failed: %s\n", strerror(errno));
close(fd);
return -1;
}
return fd;
}
int main(int argc, char *argv[])
{
char buf[128];
int fd, len;
uint16_t msglen;
fd = make_connection();
if (fd < 0)
{
return 1;
}
while (1)
{
len = recv(fd, &msglen, sizeof(msglen), 0);
if (len != sizeof(msglen))
{
break;
}
msglen = ntohs(msglen);
while (msglen)
{
if (sizeof(buf) > msglen)
{
len = msglen;
}
else
{
len = sizeof(buf);
}
len = recv(fd, &buf, len, 0);
if (len < 0)
{
break;
}
msglen -= len;
printf("%.*s", len, buf);
}
printf("\n");
if (len < 0)
{
break;
}
}
fprintf(stderr, "reading from socket failed: %s\n", strerror(errno));
close(fd);
return 1;
}
@@ -1,324 +0,0 @@
/*
* Copyright (C) 2011 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "duplicheck_listener.h"
#include <daemon.h>
#include <threading/mutex.h>
#include <collections/hashtable.h>
#include <encoding/payloads/delete_payload.h>
#include <processing/jobs/delete_ike_sa_job.h>
typedef struct private_duplicheck_listener_t private_duplicheck_listener_t;
/**
* Private data of an duplicheck_listener_t object.
*/
struct private_duplicheck_listener_t {
/**
* Public duplicheck_listener_t interface.
*/
duplicheck_listener_t public;
/**
* Socket to send notifications to
*/
duplicheck_notify_t *notify;
/**
* Mutex to lock hashtables
*/
mutex_t *mutex;
/**
* Hashtable of active IKE_SAs, identification_t => entry_t
*/
hashtable_t *active;
/**
* Hashtable with active liveness checks, identification_t => entry_t
*/
hashtable_t *checking;
};
/**
* Entry for hashtables
*/
typedef struct {
/** peer identity */
identification_t *id;
/** list of IKE_SA identifiers, ike_sa_id_t */
linked_list_t *sas;
} entry_t;
/**
* Destroy a hashtable entry
*/
static void entry_destroy(entry_t *this)
{
this->id->destroy(this->id);
this->sas->destroy_offset(this->sas, offsetof(ike_sa_id_t, destroy));
free(this);
}
/**
* Hashtable hash function
*/
static u_int hash(identification_t *key)
{
return chunk_hash(key->get_encoding(key));
}
/**
* Hashtable equals function
*/
static bool equals(identification_t *a, identification_t *b)
{
return a->equals(a, b);
}
/**
* Put an IKE_SA identifier to hashtable
*/
static void put(hashtable_t *table, identification_t *id, ike_sa_id_t *sa)
{
entry_t *entry;
entry = table->get(table, id);
if (!entry)
{
INIT(entry,
.id = id->clone(id),
.sas = linked_list_create(),
);
table->put(table, entry->id, entry);
}
entry->sas->insert_last(entry->sas, sa->clone(sa));
}
/**
* Purge an entry from table if it has no IKE_SA identifiers
*/
static void remove_if_empty(hashtable_t *table, entry_t *entry)
{
if (entry->sas->get_count(entry->sas) == 0)
{
entry = table->remove(table, entry->id);
if (entry)
{
entry_destroy(entry);
}
}
}
/**
* Remove the first entry found in the table for the given id
*/
static ike_sa_id_t *remove_first(hashtable_t *table, identification_t *id)
{
ike_sa_id_t *sa = NULL;
entry_t *entry;
entry = table->get(table, id);
if (entry)
{
entry->sas->remove_first(entry->sas, (void**)&sa);
remove_if_empty(table, entry);
}
return sa;
}
/**
* Remove a specific IKE_SA ID for the given identity
*/
static bool remove_specific(hashtable_t *table, identification_t *id,
ike_sa_id_t *sa)
{
enumerator_t *enumerator;
bool found = FALSE;
entry_t *entry;
ike_sa_id_t *current;
entry = table->get(table, id);
if (entry)
{
enumerator = entry->sas->create_enumerator(entry->sas);
while (enumerator->enumerate(enumerator, &current))
{
if (sa->equals(sa, current))
{
entry->sas->remove_at(entry->sas, enumerator);
current->destroy(current);
found = TRUE;
break;
}
}
enumerator->destroy(enumerator);
if (found)
{
remove_if_empty(table, entry);
}
}
return found;
}
METHOD(listener_t, ike_rekey, bool,
private_duplicheck_listener_t *this, ike_sa_t *old, ike_sa_t *new)
{
this->mutex->lock(this->mutex);
remove_specific(this->active, old->get_other_id(old), old->get_id(old));
put(this->active, new->get_other_id(new), new->get_id(new));
this->mutex->unlock(this->mutex);
return TRUE;
}
METHOD(listener_t, ike_updown, bool,
private_duplicheck_listener_t *this, ike_sa_t *ike_sa, bool up)
{
identification_t *id;
ike_sa_id_t *sa;
id = ike_sa->get_other_id(ike_sa);
this->mutex->lock(this->mutex);
if (up)
{
/* another IKE_SA for this identity active? */
sa = remove_first(this->active, id);
if (sa)
{
DBG1(DBG_CFG, "detected duplicate IKE_SA for '%Y', "
"triggering delete for old IKE_SA", id);
put(this->checking, id, sa);
lib->processor->queue_job(lib->processor,
(job_t*)delete_ike_sa_job_create(sa, TRUE));
sa->destroy(sa);
}
/* register IKE_SA as the new active */
sa = ike_sa->get_id(ike_sa);
put(this->active, id, sa);
}
else
{
sa = ike_sa->get_id(ike_sa);
/* check if closing an IKE_SA currently in checking state */
if (remove_specific(this->checking, id, sa))
{
DBG1(DBG_CFG, "delete for duplicate IKE_SA '%Y' timed out, "
"keeping new IKE_SA", id);
}
/* check normal close of IKE_SA */
remove_specific(this->active, id, sa);
}
this->mutex->unlock(this->mutex);
return TRUE;
}
METHOD(listener_t, message_hook, bool,
private_duplicheck_listener_t *this, ike_sa_t *ike_sa,
message_t *message, bool incoming, bool plain)
{
if (incoming && plain && !message->get_request(message))
{
identification_t *id;
ike_sa_id_t *sa;
id = ike_sa->get_other_id(ike_sa);
sa = ike_sa->get_id(ike_sa);
this->mutex->lock(this->mutex);
if (remove_specific(this->checking, id, sa))
{
DBG1(DBG_CFG, "got a response on a duplicate IKE_SA for '%Y', "
"deleting new IKE_SA", id);
charon->bus->alert(charon->bus, ALERT_UNIQUE_KEEP);
sa = remove_first(this->active, id);
if (sa)
{
lib->processor->queue_job(lib->processor,
(job_t*)delete_ike_sa_job_create(sa, TRUE));
sa->destroy(sa);
}
this->mutex->unlock(this->mutex);
this->notify->send(this->notify, id);
}
else
{
this->mutex->unlock(this->mutex);
}
}
return TRUE;
}
METHOD(duplicheck_listener_t, destroy, void,
private_duplicheck_listener_t *this)
{
enumerator_t *enumerator;
identification_t *key;
entry_t *value;
enumerator = this->active->create_enumerator(this->active);
while (enumerator->enumerate(enumerator, &key, &value))
{
entry_destroy(value);
}
enumerator->destroy(enumerator);
enumerator = this->checking->create_enumerator(this->checking);
while (enumerator->enumerate(enumerator, &key, &value))
{
entry_destroy(value);
}
enumerator->destroy(enumerator);
this->active->destroy(this->active);
this->checking->destroy(this->checking);
this->mutex->destroy(this->mutex);
free(this);
}
/**
* See header
*/
duplicheck_listener_t *duplicheck_listener_create(duplicheck_notify_t *notify)
{
private_duplicheck_listener_t *this;
INIT(this,
.public = {
.listener = {
.ike_rekey = _ike_rekey,
.ike_updown = _ike_updown,
.message = _message_hook,
},
.destroy = _destroy,
},
.notify = notify,
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.active = hashtable_create((hashtable_hash_t)hash,
(hashtable_equals_t)equals, 32),
.checking = hashtable_create((hashtable_hash_t)hash,
(hashtable_equals_t)equals, 2),
);
return &this->public;
}
@@ -1,55 +0,0 @@
/*
* Copyright (C) 2011 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup duplicheck_listener duplicheck_listener
* @{ @ingroup duplicheck
*/
#ifndef DUPLICHECK_LISTENER_H_
#define DUPLICHECK_LISTENER_H_
#include "duplicheck_notify.h"
#include <bus/listeners/listener.h>
typedef struct duplicheck_listener_t duplicheck_listener_t;
/**
* Listener checking for duplicates.
*/
struct duplicheck_listener_t {
/**
* Implements listener_t interface.
*/
listener_t listener;
/**
* Destroy a duplicheck_listener_t.
*/
void (*destroy)(duplicheck_listener_t *this);
};
/**
* Create a duplicheck_listener instance.
*
* @param notify socket to send notifications to
* @return listener
*/
duplicheck_listener_t *duplicheck_listener_create(duplicheck_notify_t *notify);
#endif /** DUPLICHECK_LISTENER_H_ @}*/
@@ -1,44 +0,0 @@
/*
* Copyright (C) 2013 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup duplicheck_msg duplicheck_msg
* @{ @ingroup duplicheck
*/
#ifndef DUPLICHECK_MSG_H_
#define DUPLICHECK_MSG_H_
#include <sys/types.h>
/**
* Default Unix socket to connect to
*/
#define DUPLICHECK_SOCKET IPSEC_PIDDIR "/charon.dck"
typedef struct duplicheck_msg_t duplicheck_msg_t;
/**
* Message exchanged over duplicheck socket
*/
struct duplicheck_msg_t {
/** length of the identity following, in network order (excluding len). */
uint16_t len;
/** identity string, not null terminated */
char identity[];
} __attribute__((__packed__));
#endif /** DUPLICHECK_MSG_H_ @}*/
@@ -1,146 +0,0 @@
/*
* Copyright (C) 2011 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "duplicheck_notify.h"
#include "duplicheck_msg.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <daemon.h>
#include <threading/mutex.h>
#include <threading/thread.h>
#include <collections/linked_list.h>
#include <processing/jobs/callback_job.h>
typedef struct private_duplicheck_notify_t private_duplicheck_notify_t;
/**
* Private data of an duplicheck_notify_t object.
*/
struct private_duplicheck_notify_t {
/**
* Public duplicheck_notify_t interface.
*/
duplicheck_notify_t public;
/**
* Mutex to lock list
*/
mutex_t *mutex;
/**
* List of connected clients, as stream_t
*/
linked_list_t *connected;
/**
* stream service accepting connections
*/
stream_service_t *service;
};
/**
* Accept duplicheck notification connections
*/
static bool on_accept(private_duplicheck_notify_t *this, stream_t *stream)
{
this->mutex->lock(this->mutex);
this->connected->insert_last(this->connected, stream);
this->mutex->unlock(this->mutex);
return TRUE;
}
METHOD(duplicheck_notify_t, send_, void,
private_duplicheck_notify_t *this, identification_t *id)
{
enumerator_t *enumerator;
stream_t *stream;
uint16_t nlen;
char buf[512];
int len;
len = snprintf(buf, sizeof(buf), "%Y", id);
if (len > 0 && len < sizeof(buf))
{
nlen = htons(len);
this->mutex->lock(this->mutex);
enumerator = this->connected->create_enumerator(this->connected);
while (enumerator->enumerate(enumerator, &stream))
{
if (!stream->write_all(stream, &nlen, sizeof(nlen)) ||
!stream->write_all(stream, buf, len))
{
DBG1(DBG_CFG, "sending duplicheck notify failed: %s",
strerror(errno));
this->connected->remove_at(this->connected, enumerator);
stream->destroy(stream);
}
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
}
}
METHOD(duplicheck_notify_t, destroy, void,
private_duplicheck_notify_t *this)
{
DESTROY_IF(this->service);
this->connected->destroy_offset(this->connected, offsetof(stream_t, destroy));
this->mutex->destroy(this->mutex);
free(this);
}
/**
* See header
*/
duplicheck_notify_t *duplicheck_notify_create()
{
private_duplicheck_notify_t *this;
char *uri;
INIT(this,
.public = {
.send = _send_,
.destroy = _destroy,
},
.connected = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
uri = lib->settings->get_str(lib->settings,
"%s.plugins.duplicheck.socket", "unix://" DUPLICHECK_SOCKET,
lib->ns);
this->service = lib->streams->create_service(lib->streams, uri, 3);
if (!this->service)
{
DBG1(DBG_CFG, "creating duplicheck socket failed");
destroy(this);
return NULL;
}
this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
this, JOB_PRIO_CRITICAL, 1);
return &this->public;
}
@@ -1,52 +0,0 @@
/*
* Copyright (C) 2011 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup duplicheck_notify duplicheck_notify
* @{ @ingroup duplicheck
*/
#ifndef DUPLICHECK_NOTIFY_H_
#define DUPLICHECK_NOTIFY_H_
#include <utils/identification.h>
typedef struct duplicheck_notify_t duplicheck_notify_t;
/**
* Sends notifications over a unix socket when duplicates are detected.
*/
struct duplicheck_notify_t {
/**
* Send a notification message if duplicate IKE_SA detected.
*
* @param id identity a duplicate tunnel has been detected
*/
void (*send)(duplicheck_notify_t *this, identification_t *id);
/**
* Destroy a duplicheck_notify_t.
*/
void (*destroy)(duplicheck_notify_t *this);
};
/**
* Create a duplicheck_notify instance.
*/
duplicheck_notify_t *duplicheck_notify_create();
#endif /** DUPLICHECK_NOTIFY_H_ @}*/
@@ -1,121 +0,0 @@
/*
* Copyright (C) 2011 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "duplicheck_plugin.h"
#include "duplicheck_notify.h"
#include "duplicheck_listener.h"
#include <daemon.h>
typedef struct private_duplicheck_plugin_t private_duplicheck_plugin_t;
/**
* Private data of duplicheck plugin
*/
struct private_duplicheck_plugin_t {
/**
* Implements plugin interface
*/
duplicheck_plugin_t public;
/**
* Listener doing duplicate checks
*/
duplicheck_listener_t *listener;
/**
* Notification sender facility
*/
duplicheck_notify_t *notify;
};
METHOD(plugin_t, get_name, char*,
private_duplicheck_plugin_t *this)
{
return "duplicheck";
}
/**
* Register listener
*/
static bool plugin_cb(private_duplicheck_plugin_t *this,
plugin_feature_t *feature, bool reg, void *cb_data)
{
if (reg)
{
charon->bus->add_listener(charon->bus, &this->listener->listener);
}
else
{
charon->bus->remove_listener(charon->bus, &this->listener->listener);
}
return TRUE;
}
METHOD(plugin_t, get_features, int,
private_duplicheck_plugin_t *this, plugin_feature_t *features[])
{
static plugin_feature_t f[] = {
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
PLUGIN_PROVIDE(CUSTOM, "duplicheck"),
};
*features = f;
return countof(f);
}
METHOD(plugin_t, destroy, void,
private_duplicheck_plugin_t *this)
{
this->notify->destroy(this->notify);
this->listener->destroy(this->listener);
free(this);
}
/**
* Plugin constructor
*/
PLUGIN_DEFINE(duplicheck)
{
private_duplicheck_plugin_t *this;
if (!lib->settings->get_bool(lib->settings,
"%s.plugins.duplicheck.enable", TRUE, lib->ns))
{
return NULL;
}
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
.get_features = _get_features,
.destroy = _destroy,
},
},
.notify = duplicheck_notify_create(),
);
if (!this->notify)
{
free(this);
return NULL;
}
this->listener = duplicheck_listener_create(this->notify);
return &this->public.plugin;
}
@@ -1,43 +0,0 @@
/*
* Copyright (C) 2011 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup duplicheck duplicheck
* @ingroup cplugins
*
* @defgroup duplicheck_plugin duplicheck_plugin
* @{ @ingroup duplicheck
*/
#ifndef DUPLICHECK_PLUGIN_H_
#define DUPLICHECK_PLUGIN_H_
#include <plugins/plugin.h>
typedef struct duplicheck_plugin_t duplicheck_plugin_t;
/**
* Advanced duplicate checking using liveness checks.
*/
struct duplicheck_plugin_t {
/**
* Implements plugin interface
*/
plugin_t plugin;
};
#endif /** DUPLICHECK_PLUGIN_H_ @}*/