diff options
Diffstat (limited to 'src/libcharon/network/receiver.c')
-rw-r--r-- | src/libcharon/network/receiver.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c index 6a39489b6..81dfb7018 100644 --- a/src/libcharon/network/receiver.c +++ b/src/libcharon/network/receiver.c @@ -27,6 +27,7 @@ #include <processing/jobs/process_message_job.h> #include <processing/jobs/callback_job.h> #include <crypto/hashers/hasher.h> +#include <threading/mutex.h> /** lifetime of a cookie, in seconds */ #define COOKIE_LIFETIME 10 @@ -55,6 +56,19 @@ struct private_receiver_t { receiver_t public; /** + * Registered callback for ESP packets + */ + struct { + receiver_esp_cb_t cb; + void *data; + } esp_cb; + + /** + * Mutex for ESP callback + */ + mutex_t *esp_cb_mutex; + + /** * current secret to use for cookie calculation */ char secret[SECRET_LENGTH]; @@ -433,7 +447,16 @@ static job_requeue_t receive_packets(private_receiver_t *this) } else { /* this seems to be an ESP packet */ - packet->destroy(packet); + this->esp_cb_mutex->lock(this->esp_cb_mutex); + if (this->esp_cb.cb) + { + this->esp_cb.cb(this->esp_cb.data, packet); + } + else + { + packet->destroy(packet); + } + this->esp_cb_mutex->unlock(this->esp_cb_mutex); return JOB_REQUEUE_DIRECT; } } @@ -536,11 +559,33 @@ static job_requeue_t receive_packets(private_receiver_t *this) return JOB_REQUEUE_DIRECT; } +METHOD(receiver_t, add_esp_cb, void, + private_receiver_t *this, receiver_esp_cb_t callback, void *data) +{ + this->esp_cb_mutex->lock(this->esp_cb_mutex); + this->esp_cb.cb = callback; + this->esp_cb.data = data; + this->esp_cb_mutex->unlock(this->esp_cb_mutex); +} + +METHOD(receiver_t, del_esp_cb, void, + private_receiver_t *this, receiver_esp_cb_t callback) +{ + this->esp_cb_mutex->lock(this->esp_cb_mutex); + if (this->esp_cb.cb == callback) + { + this->esp_cb.cb = NULL; + this->esp_cb.data = NULL; + } + this->esp_cb_mutex->unlock(this->esp_cb_mutex); +} + METHOD(receiver_t, destroy, void, private_receiver_t *this) { this->rng->destroy(this->rng); this->hasher->destroy(this->hasher); + this->esp_cb_mutex->destroy(this->esp_cb_mutex); free(this); } @@ -554,8 +599,11 @@ receiver_t *receiver_create() INIT(this, .public = { + .add_esp_cb = _add_esp_cb, + .del_esp_cb = _del_esp_cb, .destroy = _destroy, }, + .esp_cb_mutex = mutex_create(MUTEX_TYPE_DEFAULT), .secret_switch = now, .secret_offset = random() % now, ); |