struct GNUNET_CONTAINER_MultiHashMap *blacklist;
};
-struct NeighbourList;
+struct NeighbourMapEntry;
/**
* For each neighbour we keep a list of messages
/**
* To which neighbour does this ready list belong to?
*/
- struct NeighbourList *neighbour;
+ struct NeighbourMapEntry *neighbour;
};
/**
- * Entry in linked list of all of our current neighbours.
+ * Entry in neighbours.
*/
-struct NeighbourList
+struct NeighbourMapEntry
{
- /**
- * This is a linked list.
- */
- struct NeighbourList *next;
-
/**
* Which of our transports is connected to this peer
* and what is their status?
/**
* All known neighbours and their HELLOs.
*/
-static struct NeighbourList *neighbours;
+static struct GNUNET_CONTAINER_MultiHashMap *neighbours;
/**
* Number of neighbours we'd like to have.
* disconnected or must we ask all plugins to
* disconnect?
*/
-static void disconnect_neighbour (struct NeighbourList *n, int check);
+static void disconnect_neighbour (struct NeighbourMapEntry *n, int check);
/**
* Check the ready list for the given neighbour and if a plugin is
*
* @param nexi target peer for which to transmit
*/
-static void try_transmission_to_peer (struct NeighbourList *n);
+static void try_transmission_to_peer (struct NeighbourMapEntry *n);
struct ForeignAddressList * get_preferred_ats_address (
- struct NeighbourList *n);
+ struct NeighbourMapEntry *n);
/**
* Find an entry in the neighbour list for a particular peer.
*
* @return NULL if not found.
*/
-static struct NeighbourList *
+static struct NeighbourMapEntry *
find_neighbour (const struct GNUNET_PeerIdentity *key)
{
- struct NeighbourList *head = neighbours;
-
- while ((head != NULL) &&
- (0 != memcmp (key, &head->id, sizeof (struct GNUNET_PeerIdentity))))
- head = head->next;
- return head;
+ return GNUNET_CONTAINER_multihashmap_get (neighbours, &key->hashPubKey);
}
static int update_addr_value (struct ForeignAddressList *fal, uint32_t value , int ats_index)
p = find_transport (plugin);
if ((p == NULL) || (addr_len == 0) || (addr == NULL))
return NULL;
-
return p->api->address_to_string (NULL,
addr,
addr_len);
- return NULL;
}
struct ClientMessageQueueEntry *q;
uint16_t msize;
+ /* Client==NULL when GNUNET_SERVER_Client disconnected and was
+ * freed in client_disconnect_notification
+ */
+ if (client->client == NULL)
+ {
+ GNUNET_break (0);
+ return;
+ }
+
if ((client->message_count >= MAX_PENDING) && (GNUNET_YES == may_drop))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
*/
static void
transmit_send_ok (struct TransportClient *client,
- struct NeighbourList *n,
+ struct NeighbourMapEntry *n,
const struct GNUNET_PeerIdentity *target,
int result)
{
retry_transmission_task (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct NeighbourList *n = cls;
+ struct NeighbourMapEntry *n = cls;
n->retry_task = GNUNET_SCHEDULER_NO_TASK;
try_transmission_to_peer (n);
int result)
{
struct MessageQueue *mq = cls;
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
GNUNET_STATISTICS_update (stats,
gettext_noop ("# bytes pending with plugins"),
* @param neighbour target peer for which to transmit
*/
static void
-try_transmission_to_peer (struct NeighbourList *n)
+try_transmission_to_peer (struct NeighbourMapEntry *n)
{
struct ReadyList *rl;
struct MessageQueue *mq;
struct GNUNET_TIME_Relative timeout,
const char *message_buf,
size_t message_buf_size,
- int is_internal, struct NeighbourList *neighbour)
+ int is_internal, struct NeighbourMapEntry *neighbour)
{
struct MessageQueue *mq;
* @param n neighbour to PING
*/
static void
-transmit_plain_ping (struct NeighbourList *n)
+transmit_plain_ping (struct NeighbourMapEntry *n)
{
struct ValidationEntry *ve;
struct TransportPingMessage ping;
* @return selected address, NULL if we have none
*/
struct ForeignAddressList *
-find_ready_address(struct NeighbourList *neighbour)
+find_ready_address(struct NeighbourMapEntry *neighbour)
{
struct ReadyList *head = neighbour->plugins;
struct ForeignAddressList *addresses;
}
+
+static int
+transmit_our_hello_if_pong (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct NeighbourMapEntry *npos = value;
+
+ if (GNUNET_YES != npos->received_pong)
+ return GNUNET_OK;
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+ "Transmitting updated `%s' to neighbour `%4s'\n",
+ "HELLO", GNUNET_i2s (&npos->id));
+#endif
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# transmitted my HELLO to other peers"),
+ 1,
+ GNUNET_NO);
+ transmit_to_peer (NULL, NULL, 0,
+ HELLO_ADDRESS_EXPIRATION,
+ (const char *) our_hello,
+ GNUNET_HELLO_size(our_hello),
+ GNUNET_NO, npos);
+ return GNUNET_OK;
+}
+
+
/**
* Construct our HELLO message from all of the addresses of
* all of the transports.
{
struct GNUNET_HELLO_Message *hello;
struct TransportClient *cpos;
- struct NeighbourList *npos;
struct GeneratorContext gc;
hello_task = GNUNET_SCHEDULER_NO_TASK;
GNUNET_free_non_null (our_hello);
our_hello = hello;
GNUNET_PEERINFO_add_peer (peerinfo, our_hello);
- for (npos = neighbours; npos != NULL; npos = npos->next)
- {
- if (GNUNET_YES != npos->received_pong)
- continue;
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
- "Transmitting updated `%s' to neighbour `%4s'\n",
- "HELLO", GNUNET_i2s (&npos->id));
-#endif
- GNUNET_STATISTICS_update (stats,
- gettext_noop ("# transmitted my HELLO to other peers"),
- 1,
- GNUNET_NO);
- transmit_to_peer (NULL, NULL, 0,
- HELLO_ADDRESS_EXPIRATION,
- (const char *) our_hello,
- GNUNET_HELLO_size(our_hello),
- GNUNET_NO, npos);
- }
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ &transmit_our_hello_if_pong,
+ NULL);
}
*/
static void
try_fast_reconnect (struct TransportPlugin *p,
- struct NeighbourList *nl)
+ struct NeighbourMapEntry *nl)
{
/* FIXME-MW: fast reconnect / transport switching not implemented... */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
struct Session *session)
{
struct TransportPlugin *p = cls;
- struct NeighbourList *nl;
+ struct NeighbourMapEntry *nl;
struct ReadyList *rl;
struct ForeignAddressList *pos;
struct ForeignAddressList *prev;
GNUNET_SCHEDULER_cancel (pos->revalidate_task);
pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
}
- GNUNET_free_non_null(pos->ressources);
- GNUNET_free_non_null(pos->quality);
+ GNUNET_free_non_null (pos->ressources);
+ GNUNET_free_non_null (pos->quality);
#if HAVE_LIBGLPK
ats_modify_problem_state (ats, ATS_MODIFIED);
#endif
GNUNET_free (pos);
return;
}
+ pos->connected = GNUNET_NO;
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# connected addresses"),
+ -1,
+ GNUNET_NO);
GNUNET_free (pos);
if (nl->received_pong == GNUNET_NO)
* @return NULL if no such entry exists
*/
static struct ForeignAddressList *
-find_peer_address(struct NeighbourList *neighbour,
+find_peer_address(struct NeighbourMapEntry *neighbour,
const char *tname,
struct Session *session,
const char *addr,
* @return NULL if we do not have a transport plugin for 'tname'
*/
static struct ForeignAddressList *
-add_peer_address (struct NeighbourList *neighbour,
+add_peer_address (struct NeighbourMapEntry *neighbour,
const char *tname,
struct Session *session,
const char *addr,
neighbour_timeout_task (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct NeighbourList *n = cls;
+ struct NeighbourMapEntry *n = cls;
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
* Add the given address to the list of foreign addresses
* available for the given peer (check for duplicates).
*
- * @param cls the respective 'struct NeighbourList' to update
+ * @param cls the respective 'struct NeighbourMapEntry' to update
* @param tname name of the transport
* @param expiration expiration time
* @param addr the address
const void *addr,
uint16_t addrlen)
{
- struct NeighbourList *n = cls;
+ struct NeighbourMapEntry *n = cls;
struct ForeignAddressList *fal;
int try;
* Add addresses in validated HELLO "h" to the set of addresses
* we have for this peer.
*
- * @param cls closure ('struct NeighbourList*')
+ * @param cls closure ('struct NeighbourMapEntry*')
* @param peer id of the peer, NULL for last call
* @param h hello message for the peer (can be NULL)
* @param err_msg NULL if successful, otherwise contains error message
const struct GNUNET_HELLO_Message *h,
const char *err_msg)
{
- struct NeighbourList *n = cls;
+ struct NeighbourMapEntry *n = cls;
if (err_msg != NULL)
{
* @param do_hello should we schedule transmitting a HELLO
* @return the new neighbour list entry
*/
-static struct NeighbourList *
+static struct NeighbourMapEntry *
setup_new_neighbour (const struct GNUNET_PeerIdentity *peer,
int do_hello)
{
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
struct TransportPlugin *tp;
struct ReadyList *rl;
gettext_noop ("# active neighbours"),
1,
GNUNET_NO);
- n = GNUNET_malloc (sizeof (struct NeighbourList));
- n->next = neighbours;
- neighbours = n;
+ n = GNUNET_malloc (sizeof (struct NeighbourMapEntry));
n->id = *peer;
n->peer_timeout =
GNUNET_TIME_relative_to_absolute
n->distance = -1;
n->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
&neighbour_timeout_task, n);
+ GNUNET_CONTAINER_multihashmap_put (neighbours,
+ &n->id.hashPubKey,
+ n,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
if (do_hello)
{
GNUNET_STATISTICS_update (stats,
* @param n NULL if communication is not acceptable
*/
typedef void (*SetupContinuation)(void *cls,
- struct NeighbourList *n);
+ struct NeighbourMapEntry *n);
/**
/**
- * Obtain a 'struct NeighbourList' for the given peer. If such an entry
+ * Obtain a 'struct NeighbourMapEntry' for the given peer. If such an entry
* does not yet exist, check the blacklist. If the blacklist says creating
* one is acceptable, create one and call the continuation; otherwise
* call the continuation with NULL.
*
- * @param peer peer to setup or look up a struct NeighbourList for
+ * @param peer peer to setup or look up a struct NeighbourMapEntry for
* @param do_hello should we also schedule sending our HELLO to the peer
* if this is a new record
* @param cont function to call with the 'struct NeigbhbourList*'
SetupContinuation cont,
void *cont_cls)
{
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
struct BlacklistCheck *bc;
n = find_neighbour(peer);
* Function called with the result of querying a new blacklister about
* it being allowed (or not) to continue to talk to an existing neighbour.
*
- * @param cls the original 'struct NeighbourList'
+ * @param cls the original 'struct NeighbourMapEntry'
* @param n NULL if we need to disconnect
*/
static void
confirm_or_drop_neighbour (void *cls,
- struct NeighbourList *n)
+ struct NeighbourMapEntry *n)
{
- struct NeighbourList * orig = cls;
+ struct NeighbourMapEntry * orig = cls;
if (n == NULL)
{
}
+struct TestConnectionContext
+{
+ int first;
+
+ struct Blacklisters *bl;
+};
+
+
+static int
+test_connection_ok (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct TestConnectionContext *tcc = cls;
+ struct NeighbourMapEntry *n = value;
+ struct BlacklistCheck *bc;
+
+
+ bc = GNUNET_malloc (sizeof (struct BlacklistCheck));
+ GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc);
+ bc->peer = n->id;
+ bc->do_hello = GNUNET_NO;
+ bc->cont = &confirm_or_drop_neighbour;
+ bc->cont_cls = n;
+ bc->bl_pos = tcc->bl;
+ if (GNUNET_YES == tcc->first)
+ {
+ /* all would wait for the same client, no need to
+ create more than just the first task right now */
+ bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
+ bc);
+ tcc->first = GNUNET_NO;
+ }
+ return GNUNET_OK;
+}
+
+
/**
* Handle a request to start a blacklist.
*
const struct GNUNET_MessageHeader *message)
{
struct Blacklisters *bl;
- struct BlacklistCheck *bc;
- struct NeighbourList *n;
+ struct TestConnectionContext tcc;
bl = bl_head;
while (bl != NULL)
GNUNET_SERVER_client_keep (client);
GNUNET_CONTAINER_DLL_insert_after (bl_head, bl_tail, bl_tail, bl);
/* confirm that all existing connections are OK! */
- n = neighbours;
- while (NULL != n)
- {
- bc = GNUNET_malloc (sizeof (struct BlacklistCheck));
- GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc);
- bc->peer = n->id;
- bc->do_hello = GNUNET_NO;
- bc->cont = &confirm_or_drop_neighbour;
- bc->cont_cls = n;
- bc->bl_pos = bl;
- if (n == neighbours) /* all would wait for the same client, no need to
- create more than just the first task right now */
- bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
- bc);
- n = n->next;
- }
+ tcc.bl = bl;
+ tcc.first = GNUNET_YES;
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ &test_connection_ok,
+ &tcc);
}
struct ForeignAddressList *peer_address = cls;
struct TransportPlugin *tp;
struct ValidationEntry *va;
- struct NeighbourList *neighbour;
+ struct NeighbourMapEntry *neighbour;
struct TransportPingMessage ping;
struct CheckAddressExistsClosure caec;
char * message_buf;
HELLO_VERIFICATION_TIMEOUT,
message_buf, tsize,
GNUNET_YES, neighbour);
- GNUNET_free(message_buf);
+ GNUNET_free (message_buf);
schedule_next_ping (peer_address);
}
*/
static void
handle_payload_message (const struct GNUNET_MessageHeader *message,
- struct NeighbourList *n)
+ struct NeighbourMapEntry *n)
{
struct InboundMessage *im;
struct TransportClient *cpos;
unsigned int challenge = ntohl(pong->challenge);
struct GNUNET_HELLO_Message *hello;
struct GNUNET_PeerIdentity target;
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
struct ForeignAddressList *fal;
struct OwnAddressList *oal;
struct TransportPlugin *tp;
*/
static void
transmit_hello_and_ping (void *cls,
- struct NeighbourList *neighbour)
+ struct NeighbourMapEntry *neighbour)
{
struct ValidationEntry *va = cls;
struct ForeignAddressList *peer_address;
HELLO_VERIFICATION_TIMEOUT,
message_buf, tsize,
GNUNET_YES, neighbour);
- GNUNET_free(message_buf);
+ GNUNET_free (message_buf);
}
struct GNUNET_HELLO_Message *plain_hello;
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
struct GNUNET_PeerIdentity target;
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
if (err_msg != NULL)
{
const struct GNUNET_HELLO_Message *hello;
struct CheckHelloValidatedContext *chvc;
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey;
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
#if DEBUG_TRANSPORT_HELLO > 2
char *my_id;
#endif
}
#if BREAK_TESTS
- struct NeighbourList *temp_neighbor = find_neighbour(&target);
+ struct NeighbourMapEntry *temp_neighbor = find_neighbour(&target);
if ((NULL != temp_neighbor))
{
fprintf(stderr, "Already know peer, ignoring hello\n");
#if DEBUG_TRANSPORT_HELLO > 2
if (plugin != NULL)
{
- my_id = GNUNET_strdup(GNUNET_i2s(plugin->env.my_identity));
#if DEBUG_TRANSPORT
+ my_id = GNUNET_strdup(GNUNET_i2s(plugin->env.my_identity));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"%s: Starting validation of `%s' message for `%4s' via '%s' of size %u\n",
my_id,
GNUNET_i2s (&target),
plugin->short_name,
GNUNET_HELLO_size(hello));
+ GNUNET_free (my_id);
#endif
- GNUNET_free(my_id);
}
#endif
chvc = GNUNET_malloc (sizeof (struct CheckHelloValidatedContext) + hsize);
* regardless of whether other addresses exist.
*/
static void
-disconnect_neighbour (struct NeighbourList *n, int check)
+disconnect_neighbour (struct NeighbourMapEntry *n, int check)
{
struct ReadyList *rpos;
- struct NeighbourList *npos;
- struct NeighbourList *nprev;
struct MessageQueue *mq;
struct ForeignAddressList *peer_addresses;
struct ForeignAddressList *peer_pos;
GNUNET_SCHEDULER_cancel (peer_pos->revalidate_task);
peer_pos->revalidate_task = GNUNET_SCHEDULER_NO_TASK;
}
- GNUNET_free(peer_pos->ressources);
+ GNUNET_free (peer_pos->ressources);
peer_pos->ressources = NULL;
- GNUNET_free(peer_pos->quality);
+ GNUNET_free (peer_pos->quality);
peer_pos->ressources = NULL;
- GNUNET_free(peer_pos);
+ GNUNET_free (peer_pos);
}
GNUNET_free (rpos);
}
n->piter = NULL;
}
- /* remove n from neighbours list */
- nprev = NULL;
- npos = neighbours;
- while ((npos != NULL) && (npos != n))
- {
- nprev = npos;
- npos = npos->next;
- }
- GNUNET_assert (npos != NULL);
- if (nprev == NULL)
- neighbours = n->next;
- else
- nprev->next = n->next;
-
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_remove (neighbours,
+ &n->id.hashPubKey,
+ n));
/* finally, free n itself */
GNUNET_STATISTICS_update (stats,
gettext_noop ("# active neighbours"),
struct SessionHeader *session_header = (struct SessionHeader*) session;
struct TransportPingMessage *ping;
struct TransportPongMessage *pong;
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
struct ReadyList *rl;
struct ForeignAddressList *fal;
struct OwnAddressList *oal;
struct ReadyList *service_context;
struct ForeignAddressList *peer_address;
uint16_t msize;
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
struct GNUNET_TIME_Relative ret;
uint32_t distance;
int c;
return ret;
}
+
+static int
+notify_client_about_neighbour (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct TransportClient *c = cls;
+ struct NeighbourMapEntry *n = value;
+ struct ConnectInfoMessage * cim;
+ uint32_t ats_count;
+ size_t size;
+
+ if (GNUNET_YES != n->received_pong)
+ return GNUNET_OK;
+
+ ats_count = 2;
+ size = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
+ cim = GNUNET_malloc (size);
+ cim->header.size = htons (size);
+ cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
+ cim->ats_count = htonl(ats_count);
+ (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ (&(cim->ats))[2].value = htonl (0);
+ if (GNUNET_YES == n->received_pong)
+ {
+ (&cim->ats)[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
+ (&cim->ats)[0].value = htonl (n->distance);
+ (&cim->ats)[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
+ (&cim->ats)[1].value = htonl ((uint32_t) n->latency.rel_value);
+ cim->id = n->id;
+ transmit_to_client (c, &cim->header, GNUNET_NO);
+ }
+ GNUNET_free (cim);
+ return GNUNET_OK;
+}
+
+
/**
* Handle START-message. This is the first message sent to us
* by any client which causes us to add it to our list.
{
const struct StartMessage *start;
struct TransportClient *c;
- struct ConnectInfoMessage * cim;
- struct NeighbourList *n;
- uint32_t ats_count;
- size_t size;
start = (const struct StartMessage*) message;
#if DEBUG_TRANSPORT
(const struct GNUNET_MessageHeader *) our_hello,
GNUNET_NO);
/* tell new client about all existing connections */
- ats_count = 2;
- size = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
- if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
- {
- GNUNET_break(0);
- }
- cim = GNUNET_malloc (size);
- cim->header.size = htons (size);
- cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
- cim->ats_count = htonl(ats_count);
- (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
- (&(cim->ats))[2].value = htonl (0);
- n = neighbours;
- while (n != NULL)
- {
- if (GNUNET_YES == n->received_pong)
- {
- (&cim->ats)[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
- (&cim->ats)[0].value = htonl (n->distance);
- (&cim->ats)[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
- (&cim->ats)[1].value = htonl ((uint32_t) n->latency.rel_value);
- cim->id = n->id;
- transmit_to_client (c, &cim->header, GNUNET_NO);
- }
- n = n->next;
- }
- GNUNET_free (cim);
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ ¬ify_client_about_neighbour,
+ c);
}
else
{
*/
static void
transmit_client_message (void *cls,
- struct NeighbourList *n)
+ struct NeighbourMapEntry *n)
{
struct TransmitClientMessageContext *tcmc = cls;
struct TransportClient *tc;
{
const struct QuotaSetMessage *qsm =
(const struct QuotaSetMessage *) message;
- struct NeighbourList *n;
+ struct NeighbourMapEntry *n;
GNUNET_STATISTICS_update (stats,
gettext_noop ("# SET QUOTA messages received"),
}
else
{
+ GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
}
}
const char *address;
uint16_t size;
struct GNUNET_SERVER_TransmitContext *tc;
- struct GNUNET_TIME_Absolute timeout;
struct GNUNET_TIME_Relative rtimeout;
int32_t numeric;
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- timeout = GNUNET_TIME_absolute_ntoh (alum->timeout);
- rtimeout = GNUNET_TIME_absolute_get_remaining (timeout);
+ rtimeout = GNUNET_TIME_relative_ntoh (alum->timeout);
numeric = ntohl (alum->numeric_only);
lsPlugin = find_transport (nameTransport);
if (NULL == lsPlugin)
const struct GNUNET_MessageHeader *message)
{
const struct PeerAddressLookupMessage *peer_address_lookup;
- struct NeighbourList *neighbor_iterator;
+ struct NeighbourMapEntry *neighbor_iterator;
struct ReadyList *ready_iterator;
struct ForeignAddressList *foreign_address_iterator;
struct TransportPlugin *transport_plugin;
uint16_t size;
struct GNUNET_SERVER_TransmitContext *tc;
- struct GNUNET_TIME_Absolute timeout;
struct GNUNET_TIME_Relative rtimeout;
char *addr_buf;
}
peer_address_lookup = (const struct PeerAddressLookupMessage *) message;
- timeout = GNUNET_TIME_absolute_ntoh (peer_address_lookup->timeout);
- rtimeout = GNUNET_TIME_absolute_get_remaining (timeout);
+ rtimeout = GNUNET_TIME_relative_ntoh (peer_address_lookup->timeout);
- neighbor_iterator = neighbours;
- while (neighbor_iterator != NULL)
- {
- if (0 == memcmp(&neighbor_iterator->id, &peer_address_lookup->peer, sizeof(struct GNUNET_PeerIdentity)))
- break;
- neighbor_iterator = neighbor_iterator->next;
- }
+ neighbor_iterator = find_neighbour (&peer_address_lookup->peer);
/* Found no neighbor matching this peer id (shouldn't be possible, but...) */
if (neighbor_iterator == NULL)
transport_plugin = foreign_address_iterator->ready_list->plugin;
if (foreign_address_iterator->addr != NULL)
{
- GNUNET_asprintf (&addr_buf, "%s --- %s",
+ GNUNET_asprintf (&addr_buf, "%s --- %s, %s",
a2s (transport_plugin->short_name,
foreign_address_iterator->addr,
foreign_address_iterator->addrlen),
== GNUNET_YES) ? "VALIDATED"
: "UNVALIDATED");
transmit_address_to_client(tc, addr_buf);
- GNUNET_free(addr_buf);
+ GNUNET_free (addr_buf);
}
else if (foreign_address_iterator->addrlen == 0)
{
== GNUNET_YES) ? "VALIDATED"
: "UNVALIDATED");
transmit_address_to_client (tc, addr_buf);
- GNUNET_free(addr_buf);
+ GNUNET_free (addr_buf);
}
foreign_address_iterator = foreign_address_iterator->next;
GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
}
+
+
+static int
+output_addresses (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct GNUNET_SERVER_TransmitContext *tc = cls;
+ struct NeighbourMapEntry *neighbor_iterator = value;
+ struct ForeignAddressList *foreign_address_iterator;
+ struct TransportPlugin *transport_plugin;
+ struct ReadyList *ready_iterator;
+ char *addr_buf;
+
+ ready_iterator = neighbor_iterator->plugins;
+ while (ready_iterator != NULL)
+ {
+ foreign_address_iterator = ready_iterator->addresses;
+ while (foreign_address_iterator != NULL)
+ {
+ transport_plugin = foreign_address_iterator->ready_list->plugin;
+ if (foreign_address_iterator->addr != NULL)
+ {
+ GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s",
+ GNUNET_i2s(&neighbor_iterator->id),
+ a2s (transport_plugin->short_name,
+ foreign_address_iterator->addr,
+ foreign_address_iterator->addrlen),
+ (foreign_address_iterator->connected
+ == GNUNET_YES) ? "CONNECTED"
+ : "DISCONNECTED",
+ (foreign_address_iterator->validated
+ == GNUNET_YES) ? "VALIDATED"
+ : "UNVALIDATED");
+ transmit_address_to_client (tc, addr_buf);
+ GNUNET_free (addr_buf);
+ }
+ else if (foreign_address_iterator->addrlen == 0)
+ {
+ GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s",
+ GNUNET_i2s (&neighbor_iterator->id),
+ "<inbound>",
+ (foreign_address_iterator->connected
+ == GNUNET_YES) ? "CONNECTED"
+ : "DISCONNECTED",
+ (foreign_address_iterator->validated
+ == GNUNET_YES) ? "VALIDATED"
+ : "UNVALIDATED");
+ transmit_address_to_client (tc, addr_buf);
+ GNUNET_free (addr_buf);
+ }
+
+ foreign_address_iterator = foreign_address_iterator->next;
+ }
+ ready_iterator = ready_iterator->next;
+ }
+ return GNUNET_OK;
+}
+
+
/**
* Handle AddressIterateMessage
*
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- struct NeighbourList *neighbor_iterator;
- struct ReadyList *ready_iterator;
- struct ForeignAddressList *foreign_address_iterator;
- struct TransportPlugin *transport_plugin;
-
- uint16_t size;
struct GNUNET_SERVER_TransmitContext *tc;
- char *addr_buf;
+ uint16_t size;
size = ntohs (message->size);
if (size < sizeof (struct AddressIterateMessage))
}
GNUNET_SERVER_disable_receive_done_warning (client);
tc = GNUNET_SERVER_transmit_context_create (client);
-
- neighbor_iterator = neighbours;
- while (neighbor_iterator != NULL)
- {
- ready_iterator = neighbor_iterator->plugins;
- while (ready_iterator != NULL)
- {
- foreign_address_iterator = ready_iterator->addresses;
- while (foreign_address_iterator != NULL)
- {
- transport_plugin = foreign_address_iterator->ready_list->plugin;
- if (foreign_address_iterator->addr != NULL)
- {
- GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s",
- GNUNET_i2s(&neighbor_iterator->id),
- a2s (transport_plugin->short_name,
- foreign_address_iterator->addr,
- foreign_address_iterator->addrlen),
- (foreign_address_iterator->connected
- == GNUNET_YES) ? "CONNECTED"
- : "DISCONNECTED",
- (foreign_address_iterator->validated
- == GNUNET_YES) ? "VALIDATED"
- : "UNVALIDATED");
- transmit_address_to_client (tc, addr_buf);
- GNUNET_free(addr_buf);
- }
- else if (foreign_address_iterator->addrlen == 0)
- {
- GNUNET_asprintf (&addr_buf, "%s:%s --- %s, %s",
- GNUNET_i2s (&neighbor_iterator->id),
- "<inbound>",
- (foreign_address_iterator->connected
- == GNUNET_YES) ? "CONNECTED"
- : "DISCONNECTED",
- (foreign_address_iterator->validated
- == GNUNET_YES) ? "VALIDATED"
- : "UNVALIDATED");
- transmit_address_to_client (tc, addr_buf);
- GNUNET_free(addr_buf);
- }
-
- foreign_address_iterator = foreign_address_iterator->next;
- }
- ready_iterator = ready_iterator->next;
- }
- neighbor_iterator = neighbor_iterator->next;
- }
-
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ &output_addresses,
+ tc);
GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
}
+static const struct GNUNET_MessageHeader *
+do_get_our_hello ()
+{
+ return (const struct GNUNET_MessageHeader*) our_hello;
+}
+
+
/**
* Setup the environment for this plugin.
*/
{
plug->env.cfg = cfg;
plug->env.my_identity = &my_identity;
- plug->env.our_hello = &our_hello;
+ plug->env.get_our_hello = &do_get_our_hello;
plug->env.cls = plug;
plug->env.receive = &plugin_env_receive;
plug->env.notify_address = &plugin_env_notify_address;
}
+static int
+null_mq_client_pointers (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct TransportClient *pos = cls;
+ struct NeighbourMapEntry *n = value;
+ struct MessageQueue *mq;
+
+ for (mq = n->messages_head; mq != NULL; mq = mq->next)
+ {
+ if (mq->client == pos)
+ mq->client = NULL; /* do not use anymore! */
+ }
+ return GNUNET_OK;
+}
+
+
/**
* Called whenever a client is disconnected. Frees our
* resources associated with that client.
struct ClientMessageQueueEntry *mqe;
struct Blacklisters *bl;
struct BlacklistCheck *bc;
- struct NeighbourList *n;
- struct MessageQueue *mq;
if (client == NULL)
return;
pos->message_count--;
GNUNET_free (mqe);
}
- for (n = neighbours; n != NULL; n = n->next)
- {
- for (mq = n->messages_head; mq != NULL; mq = mq->next)
- {
- if (mq->client == pos)
- mq->client = NULL; /* do not use anymore! */
- }
- }
+ if (NULL != neighbours)
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ &null_mq_client_pointers,
+ pos);
if (prev == NULL)
clients = pos->next;
else
}
+static int
+disconnect_all_neighbours (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct NeighbourMapEntry *n = value;
+
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Disconnecting peer `%4s', %s\n",
+ GNUNET_i2s(&n->id),
+ "SHUTDOWN_TASK");
+#endif
+ disconnect_neighbour (n, GNUNET_NO);
+ return GNUNET_OK;
+}
+
+
/**
* Function called when the service shuts down. Unloads our plugins
* and cancels pending validations.
struct CheckHelloValidatedContext *chvc;
shutdown_in_progress = GNUNET_YES;
- while (neighbours != NULL)
- {
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Disconnecting peer `%4s', %s\n", GNUNET_i2s(&neighbours->id),
- "SHUTDOWN_TASK");
-#endif
- disconnect_neighbour (neighbours, GNUNET_NO);
- }
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ &disconnect_all_neighbours,
+ NULL);
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Transport service is unloading plugins...\n");
explicitly!? */
GNUNET_break (bl_head == NULL);
GNUNET_break (bc_head == NULL);
+ GNUNET_CONTAINER_multihashmap_destroy (neighbours);
+ neighbours = NULL;
}
}
+#if HAVE_LIBGLPK
+struct AtsBuildContext
+{
+ struct ATS_mechanism * mechanisms;
+ struct ATS_peer *peers;
+ int c_peers;
+ int c_mechs;
+};
+
+
+static int
+find_and_count_addresses (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct AtsBuildContext *abc = cls;
+ struct NeighbourMapEntry *next = value;
+ int found_addresses = GNUNET_NO;
+
+ struct ReadyList *r_next = next->plugins;
+ while (r_next != NULL)
+ {
+ struct ForeignAddressList * a_next = r_next->addresses;
+ while (a_next != NULL)
+ {
+ abc->c_mechs++;
+ found_addresses = GNUNET_YES;
+ a_next = a_next->next;
+ }
+ r_next = r_next->next;
+ }
+ if (found_addresses)
+ abc->c_peers++;
+ return GNUNET_OK;
+}
+
+
+static int
+setup_ats_problem (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct AtsBuildContext *abc = cls;
+ struct NeighbourMapEntry *next = value;
+
+ int found_addresses = GNUNET_NO;
+ struct ReadyList *r_next = next->plugins;
+ while (r_next != NULL)
+ {
+ struct ForeignAddressList * a_next = r_next->addresses;
+ while (a_next != NULL)
+ {
+ if (found_addresses == GNUNET_NO)
+ {
+ abc->peers[abc->c_peers].peer = next->id;
+ abc->peers[abc->c_peers].m_head = NULL;
+ abc->peers[abc->c_peers].m_tail = NULL;
+ abc->peers[abc->c_peers].f = 1.0 / abc->c_mechs;
+ }
+ abc->mechanisms[abc->c_mechs].addr = a_next;
+ abc->mechanisms[abc->c_mechs].col_index = abc->c_mechs;
+ abc->mechanisms[abc->c_mechs].peer = &abc->peers[abc->c_peers];
+ abc->mechanisms[abc->c_mechs].next = NULL;
+ abc->mechanisms[abc->c_mechs].plugin = r_next->plugin;
+ abc->mechanisms[abc->c_mechs].ressources = a_next->ressources;
+ abc->mechanisms[abc->c_mechs].quality = a_next->quality;
+ GNUNET_CONTAINER_DLL_insert_tail(abc->peers[abc->c_peers].m_head,
+ abc->peers[abc->c_peers].m_tail,
+ &abc->mechanisms[abc->c_mechs]);
+ found_addresses = GNUNET_YES;
+ abc->c_mechs++;
+ a_next = a_next->next;
+ }
+ r_next = r_next->next;
+ }
+ if (found_addresses == GNUNET_YES)
+ abc->c_peers++;
+ return GNUNET_OK;
+}
+
+
static void
create_ats_information ( struct ATS_peer **p,
int * c_p,
struct ATS_mechanism ** m,
int * c_m )
{
+ struct AtsBuildContext abc;
+
#if VERBOSE_ATS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"ATS requires clean address information\n");
#endif
- struct ATS_mechanism * mechanisms;
- struct ATS_peer *peers;
- int c_peers = 0;
- int c_mechs = 0;
- struct NeighbourList *next = neighbours;
-
- while (next!=NULL)
- {
- int found_addresses = GNUNET_NO;
- struct ReadyList *r_next = next->plugins;
- while (r_next != NULL)
- {
- struct ForeignAddressList * a_next = r_next->addresses;
- while (a_next != NULL)
- {
- c_mechs++;
- found_addresses = GNUNET_YES;
- a_next = a_next->next;
- }
- r_next = r_next->next;
- }
- if (found_addresses) c_peers++;
- next = next->next;
- }
-
+ abc.c_peers = 0;
+ abc.c_mechs = 0;
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ &find_and_count_addresses,
+ &abc);
#if VERBOSE_ATS
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Found %u peers with % u transport mechanisms\n", c_peers, c_mechs);
#endif
- if ((c_peers == 0) && (c_mechs == 0))
- {
- peers = NULL;
- (*c_p) = 0;
- mechanisms = NULL;
- (*c_m) = 0;
- return;
- }
-
- mechanisms = GNUNET_malloc((1+c_mechs) * sizeof (struct ATS_mechanism));
- peers = GNUNET_malloc((1+c_peers) * sizeof (struct ATS_peer));
-
- c_mechs = 1;
- c_peers = 1;
-
- next = neighbours;
- while (next!=NULL)
+ if ( (abc.c_peers == 0) && (abc.c_mechs == 0) )
{
- int found_addresses = GNUNET_NO;
- struct ReadyList *r_next = next->plugins;
- while (r_next != NULL)
- {
- struct ForeignAddressList * a_next = r_next->addresses;
- while (a_next != NULL)
- {
- if (found_addresses == GNUNET_NO)
- {
- peers[c_peers].peer = next->id;
- peers[c_peers].m_head = NULL;
- peers[c_peers].m_tail = NULL;
- peers[c_peers].f = 1.0 / c_mechs;
- }
- mechanisms[c_mechs].addr = a_next;
- mechanisms[c_mechs].col_index = c_mechs;
- mechanisms[c_mechs].peer = &peers[c_peers];
- mechanisms[c_mechs].next = NULL;
- mechanisms[c_mechs].plugin = r_next->plugin;
- mechanisms[c_mechs].ressources = a_next->ressources;
- mechanisms[c_mechs].quality = a_next->quality;
- GNUNET_CONTAINER_DLL_insert_tail(peers[c_peers].m_head,
- peers[c_peers].m_tail,
- &mechanisms[c_mechs]);
- found_addresses = GNUNET_YES;
- c_mechs++;
- a_next = a_next->next;
- }
- r_next = r_next->next;
- }
- if (found_addresses == GNUNET_YES)
- c_peers++;
- next = next->next;
- }
- c_mechs--;
- c_peers--;
- (*c_m) = c_mechs;
- (*c_p) = c_peers;
- (*p) = peers;
- (*m) = mechanisms;
+ *p = NULL;
+ (*c_p) = 0;
+ *m = NULL;
+ (*c_m) = 0;
+ return;
+ }
+
+ abc.mechanisms = GNUNET_malloc((1+abc.c_mechs) * sizeof (struct ATS_mechanism));
+ abc.peers = GNUNET_malloc((1+abc.c_peers) * sizeof (struct ATS_peer));
+ abc.c_mechs = 1;
+ abc.c_peers = 1;
+ GNUNET_CONTAINER_multihashmap_iterate (neighbours,
+ &setup_ats_problem,
+ &abc);
+ abc.c_mechs--;
+ abc.c_peers--;
+ (*c_m) = abc.c_mechs;
+ (*c_p) = abc.c_peers;
+ (*p) = abc.peers;
+ (*m) = abc.mechanisms;
}
ats_task = GNUNET_SCHEDULER_add_delayed (ats_regular_interval,
&schedule_ats, ats);
}
+#endif
+
struct ForeignAddressList * get_preferred_ats_address (
- struct NeighbourList *n)
+ struct NeighbourMapEntry *n)
{
// TODO get ATS prefered address
return find_ready_address(n);
cfg = c;
stats = GNUNET_STATISTICS_create ("transport", cfg);
validation_map = GNUNET_CONTAINER_multihashmap_create (64);
+ neighbours = GNUNET_CONTAINER_multihashmap_create (256);
/* parse configuration */
if ((GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (c,
}
GNUNET_CONTAINER_multihashmap_destroy (validation_map);
validation_map = NULL;
+ GNUNET_CONTAINER_multihashmap_destroy (neighbours);
+ neighbours = NULL;
return;
}
}
GNUNET_CONTAINER_multihashmap_destroy (validation_map);
validation_map = NULL;
+ GNUNET_CONTAINER_multihashmap_destroy (neighbours);
+ neighbours = NULL;
GNUNET_free (keyfile);
return;
}
}
GNUNET_CONTAINER_multihashmap_destroy (validation_map);
validation_map = NULL;
+ GNUNET_CONTAINER_multihashmap_destroy (neighbours);
+ neighbours = NULL;
return;
}
GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
#if HAVE_LIBGLPK
ats = ats_init (D, U, R, v_b_min, v_n_min,
ATS_MAX_ITERATIONS, ATS_MAX_EXEC_DURATION,
- create_ats_information,
+ &create_ats_information,
ats_result_cb);
-#endif
-
- int log_problem = GNUNET_NO;
- int log_solution = GNUNET_NO;
- int overwrite_dump = GNUNET_NO;
- int minimum_peers = 0;
- int minimum_addresses = 0;
-
- log_problem = GNUNET_CONFIGURATION_get_value_yesno (cfg,
- "transport",
- "DUMP_MLP");
- log_solution = GNUNET_CONFIGURATION_get_value_yesno (cfg,
- "transport",
- "DUMP_SOLUTION");
- overwrite_dump = GNUNET_CONFIGURATION_get_value_yesno (cfg,
- "transport",
- "DUMP_OVERWRITE");
- if (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_number(cfg,
- "transport",
- "DUMP_MIN_PEERS",
- &value))
- minimum_peers = (int) value;
- if (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_number(cfg,
- "transport",
- "DUMP_MIN_ADDRS",
- &value))
- minimum_addresses = (int) value;
+ ats_set_logging_options (ats,
+ stats,
+ cfg);
GNUNET_break (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_time (cfg,
"transport",
"transport",
"ATS_MIN_INTERVAL",
&ats_minimum_interval));
-#if HAVE_LIBGLPK
- ats_set_logging_options (ats,
- stats,
- minimum_addresses,
- minimum_peers,
- overwrite_dump,
- log_solution,
- log_problem);
-#endif
if (ats != NULL)
ats_task = GNUNET_SCHEDULER_add_now (&schedule_ats, ats);
-
-
+#endif
#if DEBUG_TRANSPORT