WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
*/
/**
* @file ats/gnunet-service-ats-new.c
* @brief ats service
* @author Matthias Wachs
* @author Christian Grothoff
- *
- * TODO:
- * - implement unloading of ATS plugins
*/
#include "platform.h"
#include "gnunet_util_lib.h"
* Plugin's representation of the preference.
*/
struct GNUNET_ATS_PreferenceHandle *ph;
-
+
/**
* Details about the preference.
*/
{
/**
- * Session data exposed to the plugin.
+ * Session data exposed to the plugin.
*/
struct GNUNET_ATS_SessionData data;
* Session state in the plugin.
*/
struct GNUNET_ATS_SessionHandle *sh;
-
+
/**
* Unique ID for the session when talking with the client.
- */
+ */
uint32_t session_id;
-
+
};
* Head of DLL of preferences expressed by this client.
*/
struct ClientPreference *cp_head;
-
+
/**
* Tail of DLL of preferences expressed by this client.
*/
struct ClientPreference *cp_tail;
-
+
} application;
struct {
* Map from session IDs to `struct GNUNET_ATS_Session` objects.
*/
struct GNUNET_CONTAINER_MultiHashMap32 *sessions;
-
+
} transport;
-
+
} details;
};
* @param cls closure, NULL
* @param pid peer this is about
* @param address address the transport should try
- */
+ */
static void
suggest_cb (void *cls,
const struct GNUNET_PeerIdentity *pid,
struct GNUNET_MQ_Envelope *env;
size_t slen = strlen (address) + 1;
struct AddressSuggestionMessage *as;
-
+
if (NULL == transport_client)
{
// FIXME: stats!
return;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Suggesting address `%s' of peer `%s'\n",
+ address,
+ GNUNET_i2s (pid));
env = GNUNET_MQ_msg_extra (as,
slen,
GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION);
losses of sessions (possibly of previous transport), ignore! */
return;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Allocating %u/%u bytes for %p of peer `%s'\n",
+ ntohl (bw_in.value__),
+ ntohl (bw_out.value__),
+ session,
+ GNUNET_i2s (peer));
env = GNUNET_MQ_msg (sam,
GNUNET_MESSAGE_TYPE_ATS_SESSION_ALLOCATION);
sam->session_id = session->session_id;
/**
- * We have received a `struct ExpressPreferenceMessage` from an application client.
+ * We have received a `struct ExpressPreferenceMessage` from an application client.
*
* @param cls handle to the client
* @param msg the start message
*/
static void
handle_suggest (void *cls,
- const struct ExpressPreferenceMessage *msg)
+ const struct ExpressPreferenceMessage *msg)
{
struct Client *c = cls;
struct ClientPreference *cp;
GNUNET_SERVICE_client_drop (c->client);
return;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client suggested we talk to %s with preference %d at rate %u\n",
+ GNUNET_i2s (&msg->peer),
+ (int) ntohl (msg->pk),
+ (int) ntohl (msg->bw.value__));
cp = GNUNET_new (struct ClientPreference);
cp->client = c;
cp->pref.peer = msg->peer;
/**
- * We have received a `struct ExpressPreferenceMessage` from an application client.
+ * We have received a `struct ExpressPreferenceMessage` from an application client.
*
* @param cls handle to the client
* @param msg the start message
*/
static void
handle_suggest_cancel (void *cls,
- const struct ExpressPreferenceMessage *msg)
+ const struct ExpressPreferenceMessage *msg)
{
struct Client *c = cls;
struct ClientPreference *cp;
-
+
if (CT_NONE == c->type)
c->type = CT_APPLICATION;
if (CT_APPLICATION != c->type)
cp = cp->next)
if ( (cp->pref.pk == (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk)) &&
(cp->pref.bw.value__ == msg->bw.value__) &&
- (0 == memcmp (&cp->pref.peer,
- &msg->peer,
- sizeof (struct GNUNET_PeerIdentity))) )
+ (0 == GNUNET_memcmp (&cp->pref.peer,
+ &msg->peer)) )
break;
if (NULL == cp)
{
/**
- * Check 'session_add' message is well-formed and comes from a
+ * Check 'session_add' message is well-formed and comes from a
* transport client.
*
* @param cls client that sent the request
{
struct Client *c = cls;
const char *address = (const char *) &message[1];
- struct GNUNET_ATS_Session *session;
+ struct GNUNET_ATS_Session *session;
int inbound_only = (GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY ==
ntohs (message->header.type));
session->sh = plugin->session_add (plugin->cls,
&session->data,
address);
+ GNUNET_assert (NULL != session->sh);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Transport has new session %p to %s\n",
+ session,
+ GNUNET_i2s (&message->peer));
GNUNET_SERVICE_client_continue (c->client);
}
{
struct Client *c = cls;
struct GNUNET_ATS_Session *session;
-
+
if (CT_TRANSPORT != c->type)
{
GNUNET_break (0);
GNUNET_break (0);
GNUNET_SERVICE_client_drop (c->client);
return;
- }
+ }
+ GNUNET_assert (NULL != session->sh);
plugin->session_del (plugin->cls,
session->sh,
&session->data);
+ session->sh = NULL;
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap32_remove (c->details.transport.sessions,
session->session_id,
session));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Transport lost session %p to %s\n",
+ session,
+ GNUNET_i2s (&session->data.peer));
GNUNET_free (session);
GNUNET_SERVICE_client_continue (c->client);
}
(void) key;
GNUNET_assert (c == session->client);
+ GNUNET_assert (NULL != session->sh);
plugin->session_del (plugin->cls,
session->sh,
&session->data);
+ session->sh = NULL;
GNUNET_free (session);
return GNUNET_OK;
}
/**
- * Task run during shutdown.
+ * Task run at the end during shutdown.
*
* @param cls unused
*/
static void
-cleanup_task (void *cls)
+final_cleanup (void *cls)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "ATS shutdown initiated\n");
+ (void) cls;
if (NULL != stats)
{
GNUNET_STATISTICS_destroy (stats,
GNUNET_NO);
stats = NULL;
}
+ if (NULL != plugin)
+ {
+ GNUNET_PLUGIN_unload (plugin_name,
+ plugin);
+ plugin = NULL;
+ }
if (NULL != plugin_name)
{
GNUNET_free (plugin_name);
}
+/**
+ * Task run during shutdown.
+ *
+ * @param cls unused
+ */
+static void
+cleanup_task (void *cls)
+{
+ (void) cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "ATS shutdown initiated\n");
+ GNUNET_SCHEDULER_add_now (&final_cleanup,
+ NULL);
+}
+
+
/**
* Process template requests.
*
{
static struct GNUNET_ATS_PluginEnvironment env;
char *solver;
-
+
stats = GNUNET_STATISTICS_create ("ats",
cfg);
if (GNUNET_SYSERR ==
_("Failed to initialize solver `%s'!\n"),
plugin_name);
GNUNET_SCHEDULER_shutdown ();
- return;
+ return;
}
}
&client_disconnect_cb,
NULL,
GNUNET_MQ_hd_fixed_size (suggest,
- GNUNET_MESSAGE_TYPE_ATS_SUGGEST,
- struct ExpressPreferenceMessage,
- NULL),
+ GNUNET_MESSAGE_TYPE_ATS_SUGGEST,
+ struct ExpressPreferenceMessage,
+ NULL),
GNUNET_MQ_hd_fixed_size (suggest_cancel,
- GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL,
- struct ExpressPreferenceMessage,
- NULL),
+ GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL,
+ struct ExpressPreferenceMessage,
+ NULL),
GNUNET_MQ_hd_fixed_size (start,
GNUNET_MESSAGE_TYPE_ATS_START,
struct GNUNET_MessageHeader,
GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY,
struct SessionAddMessage,
NULL),
- GNUNET_MQ_hd_fixed_size (session_update,
+ GNUNET_MQ_hd_fixed_size (session_update,
GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE,
struct SessionUpdateMessage,
NULL),
- GNUNET_MQ_hd_fixed_size (session_del,
+ GNUNET_MQ_hd_fixed_size (session_del,
GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL,
struct SessionDelMessage,
NULL),