gnunet-service-transport_clients.c | gnunet-service-transport_clients.c | |||
---|---|---|---|---|
skipping to change at line 117 | skipping to change at line 117 | |||
*/ | */ | |||
unsigned int message_count; | unsigned int message_count; | |||
/** | /** | |||
* Is this client interested in payload messages? | * Is this client interested in payload messages? | |||
*/ | */ | |||
int send_payload; | int send_payload; | |||
}; | }; | |||
/** | /** | |||
* Client monitoring changes of active addresses of our neighbours. | ||||
*/ | ||||
struct MonitoringClient | ||||
{ | ||||
/** | ||||
* This is a doubly-linked list. | ||||
*/ | ||||
struct MonitoringClient *next; | ||||
/** | ||||
* This is a doubly-linked list. | ||||
*/ | ||||
struct MonitoringClient *prev; | ||||
/** | ||||
* Handle to the client. | ||||
*/ | ||||
struct GNUNET_SERVER_Client *client; | ||||
/** | ||||
* Peer identity to monitor the addresses of. | ||||
* Zero to monitor all neighrours. | ||||
*/ | ||||
struct GNUNET_PeerIdentity peer; | ||||
}; | ||||
/** | ||||
* Head of linked list of all clients to this service. | * Head of linked list of all clients to this service. | |||
*/ | */ | |||
static struct TransportClient *clients_head; | static struct TransportClient *clients_head; | |||
/** | /** | |||
* Tail of linked list of all clients to this service. | * Tail of linked list of all clients to this service. | |||
*/ | */ | |||
static struct TransportClient *clients_tail; | static struct TransportClient *clients_tail; | |||
/** | /** | |||
* Head of linked list of monitoring clients. | ||||
*/ | ||||
static struct MonitoringClient *monitoring_clients_head; | ||||
/** | ||||
* Tail of linked list of monitoring clients. | ||||
*/ | ||||
static struct MonitoringClient *monitoring_clients_tail; | ||||
/** | ||||
* Notification context, to send updates on changes to active addresses | ||||
* of our neighbours. | ||||
*/ | ||||
struct GNUNET_SERVER_NotificationContext *nc = NULL; | ||||
/** | ||||
* Find the internal handle associated with the given client handle | * Find the internal handle associated with the given client handle | |||
* | * | |||
* @param client server's client handle to look up | * @param client server's client handle to look up | |||
* @return internal client handle | * @return internal client handle | |||
*/ | */ | |||
static struct TransportClient * | static struct TransportClient * | |||
lookup_client (struct GNUNET_SERVER_Client *client) | lookup_client (struct GNUNET_SERVER_Client *client) | |||
{ | { | |||
struct TransportClient *tc; | struct TransportClient *tc; | |||
skipping to change at line 163 | skipping to change at line 207 | |||
static struct TransportClient * | static struct TransportClient * | |||
setup_client (struct GNUNET_SERVER_Client *client) | setup_client (struct GNUNET_SERVER_Client *client) | |||
{ | { | |||
struct TransportClient *tc; | struct TransportClient *tc; | |||
GNUNET_assert (lookup_client (client) == NULL); | GNUNET_assert (lookup_client (client) == NULL); | |||
tc = GNUNET_malloc (sizeof (struct TransportClient)); | tc = GNUNET_malloc (sizeof (struct TransportClient)); | |||
tc->client = client; | tc->client = client; | |||
#if DEBUG_TRANSPORT | #if DEBUG_TRANSPORT | |||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %X connected\n", tc); | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", tc); | |||
#endif | #endif | |||
return tc; | return tc; | |||
} | } | |||
/** | /** | |||
* Find the handle to the monitoring client associated with the given | ||||
* client handle | ||||
* | ||||
* @param client server's client handle to look up | ||||
* @return handle to the monitoring client | ||||
*/ | ||||
static struct MonitoringClient * | ||||
lookup_monitoring_client (struct GNUNET_SERVER_Client *client) | ||||
{ | ||||
struct MonitoringClient *mc; | ||||
mc = monitoring_clients_head; | ||||
while (mc != NULL) | ||||
{ | ||||
if (mc->client == client) | ||||
return mc; | ||||
mc = mc->next; | ||||
} | ||||
return NULL; | ||||
} | ||||
/** | ||||
* Setup a new monitoring client using the given server client handle and | ||||
* the peer identity. | ||||
* | ||||
* @param client server's client handle to create our internal handle for | ||||
* @param peer identity of the peer to monitor the addresses of, | ||||
* zero to monitor all neighrours. | ||||
* @return handle to the new monitoring client | ||||
*/ | ||||
static struct MonitoringClient * | ||||
setup_monitoring_client (struct GNUNET_SERVER_Client *client, | ||||
struct GNUNET_PeerIdentity *peer) | ||||
{ | ||||
struct MonitoringClient *mc; | ||||
GNUNET_assert (lookup_monitoring_client (client) == NULL); | ||||
mc = GNUNET_malloc (sizeof (struct MonitoringClient)); | ||||
mc->client = client; | ||||
mc->peer = *peer; | ||||
GNUNET_CONTAINER_DLL_insert (monitoring_clients_head, | ||||
monitoring_clients_tail, | ||||
mc); | ||||
GNUNET_SERVER_notification_context_add (nc, client); | ||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||||
"Client %p started monitoring of the peer `%s'\n", | ||||
mc, GNUNET_i2s (peer)); | ||||
return mc; | ||||
} | ||||
/** | ||||
* Function called to notify a client about the socket being ready to | * Function called to notify a client about the socket being ready to | |||
* queue more data. "buf" will be NULL and "size" zero if the socket | * queue more data. "buf" will be NULL and "size" zero if the socket | |||
* was closed for writing in the meantime. | * was closed for writing in the meantime. | |||
* | * | |||
* @param cls closure | * @param cls closure | |||
* @param size number of bytes available in buf | * @param size number of bytes available in buf | |||
* @param buf where the callee should write the message | * @param buf where the callee should write the message | |||
* @return number of bytes written to buf | * @return number of bytes written to buf | |||
*/ | */ | |||
static size_t | static size_t | |||
skipping to change at line 207 | skipping to change at line 303 | |||
cbuf = buf; | cbuf = buf; | |||
tsize = 0; | tsize = 0; | |||
while (NULL != (q = tc->message_queue_head)) | while (NULL != (q = tc->message_queue_head)) | |||
{ | { | |||
msg = (const struct GNUNET_MessageHeader *) &q[1]; | msg = (const struct GNUNET_MessageHeader *) &q[1]; | |||
msize = ntohs (msg->size); | msize = ntohs (msg->size); | |||
if (msize + tsize > size) | if (msize + tsize > size) | |||
break; | break; | |||
#if DEBUG_TRANSPORT | #if DEBUG_TRANSPORT | |||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | |||
"Transmitting message of type %u to client %X.\n", | "Transmitting message of type %u to client %p.\n", | |||
ntohs (msg->type), tc); | ntohs (msg->type), tc); | |||
#endif | #endif | |||
GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_ tail, | GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_ tail, | |||
q); | q); | |||
tc->message_count--; | tc->message_count--; | |||
memcpy (&cbuf[tsize], msg, msize); | memcpy (&cbuf[tsize], msg, msize); | |||
GNUNET_free (q); | GNUNET_free (q); | |||
tsize += msize; | tsize += msize; | |||
} | } | |||
if (NULL != q) | if (NULL != q) | |||
skipping to change at line 283 | skipping to change at line 379 | |||
* Called whenever a client is disconnected. Frees our | * Called whenever a client is disconnected. Frees our | |||
* resources associated with that client. | * resources associated with that client. | |||
* | * | |||
* @param cls closure | * @param cls closure | |||
* @param client identification of the client | * @param client identification of the client | |||
*/ | */ | |||
static void | static void | |||
client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *cli ent) | client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *cli ent) | |||
{ | { | |||
struct TransportClient *tc; | struct TransportClient *tc; | |||
struct MonitoringClient *mc; | ||||
struct ClientMessageQueueEntry *mqe; | struct ClientMessageQueueEntry *mqe; | |||
if (client == NULL) | if (client == NULL) | |||
return; | return; | |||
mc = lookup_monitoring_client (client); | ||||
if (mc != NULL) | ||||
{ | ||||
GNUNET_CONTAINER_DLL_remove (monitoring_clients_head, | ||||
monitoring_clients_tail, | ||||
mc); | ||||
GNUNET_free (mc); | ||||
} | ||||
tc = lookup_client (client); | tc = lookup_client (client); | |||
if (tc == NULL) | if (tc == NULL) | |||
return; | return; | |||
#if DEBUG_TRANSPORT | #if DEBUG_TRANSPORT | |||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | |||
"Client %X disconnected, cleaning up.\n", tc); | "Client %p disconnected, cleaning up.\n", tc); | |||
#endif | #endif | |||
while (NULL != (mqe = tc->message_queue_head)) | while (NULL != (mqe = tc->message_queue_head)) | |||
{ | { | |||
GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_ tail, | GNUNET_CONTAINER_DLL_remove (tc->message_queue_head, tc->message_queue_ tail, | |||
mqe); | mqe); | |||
tc->message_count--; | tc->message_count--; | |||
GNUNET_free (mqe); | GNUNET_free (mqe); | |||
} | } | |||
GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, tc); | GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, tc); | |||
if (tc->th != NULL) | if (tc->th != NULL) | |||
skipping to change at line 367 | skipping to change at line 472 | |||
clients_handle_start (void *cls, struct GNUNET_SERVER_Client *client, | clients_handle_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
const struct GNUNET_MessageHeader *message) | const struct GNUNET_MessageHeader *message) | |||
{ | { | |||
const struct StartMessage *start; | const struct StartMessage *start; | |||
struct TransportClient *tc; | struct TransportClient *tc; | |||
uint32_t options; | uint32_t options; | |||
tc = lookup_client (client); | tc = lookup_client (client); | |||
#if DEBUG_TRANSPORT | #if DEBUG_TRANSPORT | |||
if (tc != NULL) | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | |||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | "Client %p sent START\n", tc); | |||
"Client %X sent START\n", tc); | ||||
else | ||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | ||||
"Client %X sent START\n", tc); | ||||
#endif | #endif | |||
if (tc != NULL) | if (tc != NULL) | |||
{ | { | |||
/* got 'start' twice from the same client, not allowed */ | /* got 'start' twice from the same client, not allowed */ | |||
#if DEBUG_TRANSPORT | #if DEBUG_TRANSPORT | |||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | |||
"TransportClient %X ServerClient %X sent multiple START me ssages\n", | "TransportClient %p ServerClient %p sent multiple START mes sages\n", | |||
tc, tc->client); | tc, tc->client); | |||
#endif | #endif | |||
GNUNET_break (0); | GNUNET_break (0); | |||
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | |||
return; | return; | |||
} | } | |||
start = (const struct StartMessage *) message; | start = (const struct StartMessage *) message; | |||
options = ntohl (start->options); | options = ntohl (start->options); | |||
if ((0 != (1 & options)) && | if ((0 != (1 & options)) && | |||
(0 != | (0 != | |||
skipping to change at line 675 | skipping to change at line 776 | |||
GNUNET_SERVER_transmit_context_run (tc, rtimeout); | GNUNET_SERVER_transmit_context_run (tc, rtimeout); | |||
return; | return; | |||
} | } | |||
GNUNET_SERVER_disable_receive_done_warning (client); | GNUNET_SERVER_disable_receive_done_warning (client); | |||
papi->address_pretty_printer (papi->cls, plugin_name, address, address_le n, | papi->address_pretty_printer (papi->cls, plugin_name, address, address_le n, | |||
numeric, rtimeout, &transmit_address_to_cli ent, | numeric, rtimeout, &transmit_address_to_cli ent, | |||
tc); | tc); | |||
} | } | |||
/** | /** | |||
* Compose AddressIterateResponseMessage using the given peer and address. | ||||
* | ||||
* @param peer identity of the peer | ||||
* @param address the address, NULL on disconnect | ||||
* @return composed message | ||||
*/ | ||||
static struct AddressIterateResponseMessage * | ||||
compose_address_iterate_response_message (const struct GNUNET_PeerIdentity | ||||
*peer, | ||||
const struct GNUNET_HELLO_Address | ||||
*address) | ||||
{ | ||||
struct AddressIterateResponseMessage *msg; | ||||
size_t size; | ||||
size_t tlen; | ||||
size_t alen; | ||||
char *addr; | ||||
GNUNET_assert (NULL != peer); | ||||
if (NULL != address) | ||||
{ | ||||
tlen = strlen (address->transport_name) + 1; | ||||
alen = address->address_length; | ||||
} | ||||
else | ||||
tlen = alen = 0; | ||||
size = (sizeof (struct AddressIterateResponseMessage) + alen + tlen); | ||||
msg = GNUNET_malloc (size); | ||||
msg->header.size = htons (size); | ||||
msg->header.type = | ||||
htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE); | ||||
msg->reserved = htonl (0); | ||||
msg->peer = *peer; | ||||
msg->addrlen = htonl (alen); | ||||
msg->pluginlen = htonl (tlen); | ||||
if (NULL != address) | ||||
{ | ||||
addr = (char *) &msg[1]; | ||||
memcpy (addr, address->address, alen); | ||||
memcpy (&addr[alen], address->transport_name, tlen); | ||||
} | ||||
return msg; | ||||
} | ||||
/** | ||||
* Output the active address of connected neighbours to the given client. | * Output the active address of connected neighbours to the given client. | |||
* | * | |||
* @param cls the 'struct GNUNET_SERVER_TransmitContext' for transmission t o the client | * @param cls the 'struct GNUNET_SERVER_TransmitContext' for transmission t o the client | |||
* @param peer identity of the neighbour | * @param peer identity of the neighbour | |||
* @param ats performance data | * @param ats performance data | |||
* @param ats_count number of entries in ats (excluding 0-termination) | * @param ats_count number of entries in ats (excluding 0-termination) | |||
* @param address the address | * @param address the address | |||
*/ | */ | |||
static void | static void | |||
output_address (void *cls, const struct GNUNET_PeerIdentity *peer, | output_address (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
const struct GNUNET_ATS_Information *ats, uint32_t ats_coun t, | const struct GNUNET_ATS_Information *ats, uint32_t ats_coun t, | |||
const struct GNUNET_HELLO_Address *address) | const struct GNUNET_HELLO_Address *address) | |||
{ | { | |||
struct GNUNET_SERVER_TransmitContext *tc = cls; | struct GNUNET_SERVER_TransmitContext *tc = cls; | |||
struct AddressIterateResponseMessage *msg; | struct AddressIterateResponseMessage *msg; | |||
size_t size; | ||||
size_t tlen; | ||||
size_t alen; | ||||
char *addr; | ||||
tlen = strlen (address->transport_name) + 1; | ||||
alen = address->address_length; | ||||
size = (sizeof (struct AddressIterateResponseMessage) + alen + tlen); | ||||
{ | ||||
char buf[size]; | ||||
msg = (struct AddressIterateResponseMessage *) buf; | msg = compose_address_iterate_response_message (peer, address); | |||
msg->reserved = htonl (0); | GNUNET_SERVER_transmit_context_append_message (tc, &msg->header); | |||
msg->peer = *peer; | GNUNET_free (msg); | |||
msg->addrlen = htonl (alen); | ||||
msg->pluginlen = htonl (tlen); | ||||
addr = (char *) &msg[1]; | ||||
memcpy (addr, address->address, alen); | ||||
memcpy (&addr[alen], address->transport_name, tlen); | ||||
GNUNET_SERVER_transmit_context_append_data (tc, | ||||
&buf[sizeof | ||||
(struct | ||||
GNUNET_MessageHeader) | ||||
], | ||||
size - | ||||
sizeof (struct | ||||
GNUNET_MessageHeade | ||||
r), | ||||
GNUNET_MESSAGE_TYPE_TRANSPO | ||||
RT_ADDRESS_ITERATE_RESPONSE); | ||||
} | ||||
} | } | |||
/** | /** | |||
* Client asked to obtain information about all actively used addresses | * Client asked to obtain information about all actively used addresses | |||
* of connected peers | * of connected peers | |||
* Process the request. | * Process the request. | |||
* | * | |||
* @param cls unused | * @param cls unused | |||
* @param client the client | * @param client the client | |||
* @param message the peer address information request | * @param message the peer address information request | |||
skipping to change at line 751 | skipping to change at line 873 | |||
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | |||
return; | return; | |||
} | } | |||
if (ntohs (message->size) != sizeof (struct AddressIterateMessage)) | if (ntohs (message->size) != sizeof (struct AddressIterateMessage)) | |||
{ | { | |||
GNUNET_break (0); | GNUNET_break (0); | |||
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | |||
return; | return; | |||
} | } | |||
msg = (struct AddressIterateMessage *) message; | msg = (struct AddressIterateMessage *) message; | |||
if (GNUNET_YES != ntohl (msg->one_shot)) | if ( (GNUNET_YES != ntohl (msg->one_shot)) && | |||
(NULL != lookup_monitoring_client (client)) ) | ||||
{ | { | |||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | |||
"Address monitoring not implemented\n"); | "ServerClient %p tried to start monitoring twice\n", | |||
client); | ||||
GNUNET_break (0); | ||||
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | |||
return; | return; | |||
} | } | |||
GNUNET_SERVER_disable_receive_done_warning (client); | GNUNET_SERVER_disable_receive_done_warning (client); | |||
tc = GNUNET_SERVER_transmit_context_create (client); | tc = GNUNET_SERVER_transmit_context_create (client); | |||
if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdenti ty))) | if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdenti ty))) | |||
{ | { | |||
/* iterate over all neighbours */ | /* iterate over all neighbours */ | |||
GST_neighbours_iterate (&output_address, tc); | GST_neighbours_iterate (&output_address, tc); | |||
} | } | |||
else | else | |||
{ | { | |||
/* just return one neighbour */ | /* just return one neighbour */ | |||
address = GST_neighbour_get_current_address (&msg->peer); | address = GST_neighbour_get_current_address (&msg->peer); | |||
if (address != NULL) | if (address != NULL) | |||
output_address (tc, &msg->peer, NULL, 0, address); | output_address (tc, &msg->peer, NULL, 0, address); | |||
} | } | |||
GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, | if (GNUNET_YES != ntohl (msg->one_shot)) | |||
GNUNET_MESSAGE_TYPE_TRANSPORT | setup_monitoring_client (client, &msg->peer); | |||
_ADDRESS_ITERATE_RESPONSE); | else | |||
GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, | ||||
GNUNET_MESSAGE_TYPE_TRANSPOR | ||||
T_ADDRESS_ITERATE_RESPONSE); | ||||
GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | |||
} | } | |||
/** | /** | |||
* Start handling requests from clients. | * Start handling requests from clients. | |||
* | * | |||
* @param server server used to accept clients from. | * @param server server used to accept clients from. | |||
*/ | */ | |||
void | void | |||
GST_clients_start (struct GNUNET_SERVER_Handle *server) | GST_clients_start (struct GNUNET_SERVER_Handle *server) | |||
skipping to change at line 808 | skipping to change at line 936 | |||
GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE, | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE, | |||
sizeof (struct AddressIterateMessage)}, | sizeof (struct AddressIterateMessage)}, | |||
{&GST_blacklist_handle_init, NULL, | {&GST_blacklist_handle_init, NULL, | |||
GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT, | GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT, | |||
sizeof (struct GNUNET_MessageHeader)}, | sizeof (struct GNUNET_MessageHeader)}, | |||
{&GST_blacklist_handle_reply, NULL, | {&GST_blacklist_handle_reply, NULL, | |||
GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY, | GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY, | |||
sizeof (struct BlacklistMessage)}, | sizeof (struct BlacklistMessage)}, | |||
{NULL, NULL, 0, 0} | {NULL, NULL, 0, 0} | |||
}; | }; | |||
nc = GNUNET_SERVER_notification_context_create (server, 0); | ||||
GNUNET_SERVER_add_handlers (server, handlers); | GNUNET_SERVER_add_handlers (server, handlers); | |||
GNUNET_SERVER_disconnect_notify (server, &client_disconnect_notification, | GNUNET_SERVER_disconnect_notify (server, &client_disconnect_notification, | |||
NULL); | NULL); | |||
} | } | |||
/** | /** | |||
* Stop processing clients. | * Stop processing clients. | |||
*/ | */ | |||
void | void | |||
GST_clients_stop () | GST_clients_stop () | |||
{ | { | |||
/* nothing to do */ | if (NULL != nc) | |||
{ | ||||
GNUNET_SERVER_notification_context_destroy (nc); | ||||
nc = NULL; | ||||
} | ||||
} | } | |||
/** | /** | |||
* Broadcast the given message to all of our clients. | * Broadcast the given message to all of our clients. | |||
* | * | |||
* @param msg message to broadcast | * @param msg message to broadcast | |||
* @param may_drop GNUNET_YES if the message can be dropped / is payload | * @param may_drop GNUNET_YES if the message can be dropped / is payload | |||
*/ | */ | |||
void | void | |||
GST_clients_broadcast (const struct GNUNET_MessageHeader *msg, int may_drop ) | GST_clients_broadcast (const struct GNUNET_MessageHeader *msg, int may_drop ) | |||
skipping to change at line 860 | skipping to change at line 993 | |||
const struct GNUNET_MessageHeader *msg, int may_drop) | const struct GNUNET_MessageHeader *msg, int may_drop) | |||
{ | { | |||
struct TransportClient *tc; | struct TransportClient *tc; | |||
tc = lookup_client (client); | tc = lookup_client (client); | |||
if (NULL == tc) | if (NULL == tc) | |||
return; /* client got disconnected in the meantime, drop message */ | return; /* client got disconnected in the meantime, drop message */ | |||
unicast (tc, msg, may_drop); | unicast (tc, msg, may_drop); | |||
} | } | |||
/** | ||||
* Broadcast the new active address to all clients monitoring the peer. | ||||
* | ||||
* @param peer peer this update is about (never NULL) | ||||
* @param address address, NULL on disconnect | ||||
*/ | ||||
void | ||||
GST_clients_broadcast_address_notification (const struct GNUNET_PeerIdentit | ||||
y | ||||
*peer, | ||||
const struct GNUNET_HELLO_Addre | ||||
ss | ||||
*address) | ||||
{ | ||||
struct AddressIterateResponseMessage *msg; | ||||
struct MonitoringClient *mc; | ||||
static struct GNUNET_PeerIdentity all_zeros; | ||||
msg = compose_address_iterate_response_message (peer, address); | ||||
mc = monitoring_clients_head; | ||||
while (mc != NULL) | ||||
{ | ||||
if ((0 == memcmp (&mc->peer, &all_zeros, | ||||
sizeof (struct GNUNET_PeerIdentity))) || | ||||
(0 == memcmp (&mc->peer, peer, | ||||
sizeof (struct GNUNET_PeerIdentity)))) | ||||
{ | ||||
GNUNET_SERVER_notification_context_unicast (nc, mc->client, | ||||
&msg->header, GNUNET_NO); | ||||
} | ||||
mc = mc->next; | ||||
} | ||||
GNUNET_free (msg); | ||||
} | ||||
/* end of file gnunet-service-transport_clients.c */ | /* end of file gnunet-service-transport_clients.c */ | |||
End of changes. 19 change blocks. | ||||
47 lines changed or deleted | 213 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |