daemon: Flush shunts before unloading plugins
[strongswan.git] / src / libstrongswan / fetcher / fetcher_manager.c
index 3a9e632..f36cfcf 100644 (file)
  * 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.
- *
- * $Id$
  */
 
-#define _GNU_SOURCE
-
 #include "fetcher_manager.h"
 
-#include <debug.h>
-#include <utils/linked_list.h>
-#include <utils/mutex.h>
+#include <utils/debug.h>
+#include <threading/rwlock.h>
+#include <collections/linked_list.h>
 
 typedef struct private_fetcher_manager_t private_fetcher_manager_t;
 
@@ -34,20 +30,20 @@ struct private_fetcher_manager_t {
         * public functions
         */
        fetcher_manager_t public;
-       
+
        /**
         * list of registered fetchers, as entry_t
         */
        linked_list_t *fetchers;
-       
+
        /**
         * read write lock to list
         */
-       pthread_rwlock_t lock;
+       rwlock_t *lock;
 };
 
 typedef struct {
-       /** assocaited fetcher construction function */
+       /** associated fetcher construction function */
        fetcher_constructor_t create;
        /** URL this fetcher support */
        char *url;
@@ -62,24 +58,22 @@ static void entry_destroy(entry_t *entry)
        free(entry);
 }
 
-/**
- * Implementation of fetcher_manager_t.fetch.
- */
-static status_t fetch(private_fetcher_manager_t *this,
-                                         char *url, chunk_t *response, ...)
+METHOD(fetcher_manager_t, fetch, status_t,
+       private_fetcher_manager_t *this, char *url, void *userdata, ...)
 {
        enumerator_t *enumerator;
        status_t status = NOT_SUPPORTED;
        entry_t *entry;
        bool capable = FALSE;
-       
-       pthread_rwlock_rdlock(&this->lock);
+
+       this->lock->read_lock(this->lock);
        enumerator = this->fetchers->create_enumerator(this->fetchers);
        while (enumerator->enumerate(enumerator, &entry))
        {
                fetcher_option_t opt;
                fetcher_t *fetcher;
                bool good = TRUE;
+               host_t *host;
                va_list args;
 
                /* check URL support of fetcher */
@@ -93,23 +87,45 @@ static status_t fetch(private_fetcher_manager_t *this,
                {
                        continue;
                }
-               va_start(args, response);
+               va_start(args, userdata);
                while (good)
                {
-                       opt = va_arg(args, fetcher_option_t);
+                       opt = va_arg(args, int);
                        switch (opt)
                        {
                                case FETCH_REQUEST_DATA:
-                                       good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t));
+                                       good = fetcher->set_option(fetcher, opt,
+                                                                                       va_arg(args, chunk_t));
                                        continue;
                                case FETCH_REQUEST_TYPE:
-                                       good = fetcher->set_option(fetcher, opt, va_arg(args, char*));
+                               case FETCH_REQUEST_HEADER:
+                                       good = fetcher->set_option(fetcher, opt,
+                                                                                       va_arg(args, char*));
+                                       continue;
+                               case FETCH_HTTP_VERSION_1_0:
+                                       good = fetcher->set_option(fetcher, opt);
                                        continue;
                                case FETCH_TIMEOUT:
-                                       good = fetcher->set_option(fetcher, opt, va_arg(args, u_int));
+                                       good = fetcher->set_option(fetcher, opt,
+                                                                                       va_arg(args, u_int));
+                                       continue;
+                               case FETCH_CALLBACK:
+                                       good = fetcher->set_option(fetcher, opt,
+                                                                                       va_arg(args, fetcher_callback_t));
+                                       continue;
+                               case FETCH_RESPONSE_CODE:
+                                       good = fetcher->set_option(fetcher, opt,
+                                                                                       va_arg(args, u_int*));
+                                       continue;
+                               case FETCH_SOURCEIP:
+                                       host = va_arg(args, host_t*);
+                                       if (host && !host->is_anyaddr(host))
+                                       {
+                                               good = fetcher->set_option(fetcher, opt, host);
+                                       }
                                        continue;
                                case FETCH_END:
-                                       break;;
+                                       break;
                        }
                        break;
                }
@@ -119,8 +135,8 @@ static status_t fetch(private_fetcher_manager_t *this,
                        fetcher->destroy(fetcher);
                        continue;
                }
-               
-               status = fetcher->fetch(fetcher, url, response);
+
+               status = fetcher->fetch(fetcher, url, userdata);
                fetcher->destroy(fetcher);
                /* try another fetcher only if this one does not support that URL */
                if (status == NOT_SUPPORTED)
@@ -131,40 +147,35 @@ static status_t fetch(private_fetcher_manager_t *this,
                break;
        }
        enumerator->destroy(enumerator);
-       pthread_rwlock_unlock(&this->lock);
+       this->lock->unlock(this->lock);
        if (!capable)
        {
-               DBG1("unable to fetch from %s, no capable fetcher found", url);
+               DBG1(DBG_LIB, "unable to fetch from %s, no capable fetcher found", url);
        }
        return status;
 }
 
-/**
- * Implementation of fetcher_manager_t.add_fetcher.
- */
-static void add_fetcher(private_fetcher_manager_t *this,       
-                                               fetcher_constructor_t create, char *url)
+METHOD(fetcher_manager_t, add_fetcher, void,
+       private_fetcher_manager_t *this, fetcher_constructor_t create, char *url)
 {
-       entry_t *entry = malloc_thing(entry_t);
-       
-       entry->url = strdup(url);
-       entry->create = create;
+       entry_t *entry;
 
-       pthread_rwlock_wrlock(&this->lock);
+       INIT(entry,
+               .url = strdup(url),
+               .create = create,
+       );
+       this->lock->write_lock(this->lock);
        this->fetchers->insert_last(this->fetchers, entry);
-       pthread_rwlock_unlock(&this->lock);
+       this->lock->unlock(this->lock);
 }
 
-/**
- * Implementation of fetcher_manager_t.remove_fetcher.
- */
-static void remove_fetcher(private_fetcher_manager_t *this,
-                                                  fetcher_constructor_t create)
+METHOD(fetcher_manager_t, remove_fetcher, void,
+       private_fetcher_manager_t *this, fetcher_constructor_t create)
 {
        enumerator_t *enumerator;
        entry_t *entry;
-       
-       pthread_rwlock_wrlock(&this->lock);
+
+       this->lock->write_lock(this->lock);
        enumerator = this->fetchers->create_enumerator(this->fetchers);
        while (enumerator->enumerate(enumerator, &entry))
        {
@@ -175,16 +186,14 @@ static void remove_fetcher(private_fetcher_manager_t *this,
                }
        }
        enumerator->destroy(enumerator);
-       pthread_rwlock_unlock(&this->lock);
+       this->lock->unlock(this->lock);
 }
 
-/**
- * Implementation of fetcher_manager_t.destroy
- */
-static void destroy(private_fetcher_manager_t *this)
+METHOD(fetcher_manager_t, destroy, void,
+       private_fetcher_manager_t *this)
 {
        this->fetchers->destroy_function(this->fetchers, (void*)entry_destroy);
-       pthread_rwlock_destroy(&this->lock);
+       this->lock->destroy(this->lock);
        free(this);
 }
 
@@ -193,16 +202,18 @@ static void destroy(private_fetcher_manager_t *this)
  */
 fetcher_manager_t *fetcher_manager_create()
 {
-       private_fetcher_manager_t *this = malloc_thing(private_fetcher_manager_t);
-       
-       this->public.fetch = (status_t(*)(fetcher_manager_t*, char *url, chunk_t *response, ...))fetch;
-       this->public.add_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t,char*))add_fetcher;
-       this->public.remove_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t))remove_fetcher;
-       this->public.destroy = (void(*)(fetcher_manager_t*))destroy;
-       
-       this->fetchers = linked_list_create();
-       pthread_rwlock_init(&this->lock, NULL);
-       
+       private_fetcher_manager_t *this;
+
+       INIT(this,
+               .public = {
+                       .fetch = _fetch,
+                       .add_fetcher = _add_fetcher,
+                       .remove_fetcher = _remove_fetcher,
+                       .destroy = _destroy,
+               },
+               .fetchers = linked_list_create(),
+               .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+       );
+
        return &this->public;
 }
-