aboutsummaryrefslogtreecommitdiff
path: root/src/peerinfo/gnunet-service-peerinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/peerinfo/gnunet-service-peerinfo.c')
-rw-r--r--src/peerinfo/gnunet-service-peerinfo.c259
1 files changed, 56 insertions, 203 deletions
diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c
index 2f3e2c8e1..5b2b999d6 100644
--- a/src/peerinfo/gnunet-service-peerinfo.c
+++ b/src/peerinfo/gnunet-service-peerinfo.c
@@ -89,54 +89,6 @@ struct HostEntry
89 89
90 90
91/** 91/**
92 * Entries that we still need to tell the client about.
93 */
94struct PendingEntry
95{
96
97 /**
98 * This is a linked list.
99 */
100 struct PendingEntry *next;
101
102 /**
103 * Entry to tell the client about.
104 */
105 struct HostEntry *he;
106
107};
108
109
110/**
111 * Clients to notify of changes to the peer information.
112 */
113struct NotifyList
114{
115
116 /**
117 * This is a linked list.
118 */
119 struct NotifyList *next;
120
121 /**
122 * Client to notify.
123 */
124 struct GNUNET_SERVER_Client *client;
125
126 /**
127 * Notifications pending for this entry.
128 */
129 struct PendingEntry *pending;
130
131 /**
132 * Handle for a transmit ready request.
133 */
134 struct GNUNET_CONNECTION_TransmitHandle *transmit_ctx;
135
136};
137
138
139/**
140 * The in-memory list of known hosts. 92 * The in-memory list of known hosts.
141 */ 93 */
142static struct HostEntry *hosts; 94static struct HostEntry *hosts;
@@ -144,7 +96,7 @@ static struct HostEntry *hosts;
144/** 96/**
145 * Clients to immediately notify about all changes. 97 * Clients to immediately notify about all changes.
146 */ 98 */
147static struct NotifyList *notify_list; 99static struct GNUNET_SERVER_NotificationContext *notify_list;
148 100
149/** 101/**
150 * Directory where the hellos are stored in (data/hosts) 102 * Directory where the hellos are stored in (data/hosts)
@@ -158,116 +110,23 @@ static char *trustDirectory;
158 110
159 111
160/** 112/**
161 * Transmit peer information messages from the pending queue
162 * to the client.
163 *
164 * @param cls the 'struct NotifyList' that we are processing
165 * @param size number of bytes we can transmit
166 * @param vbuf where to write the messages
167 * @return number of bytes written to vbuf
168 */
169static size_t
170transmit_pending_notification (void *cls,
171 size_t size,
172 void *vbuf)
173{
174 struct NotifyList *nl = cls;
175 char *buf = vbuf;
176 struct PendingEntry *pos;
177 struct PendingEntry *next;
178 struct InfoMessage im;
179 uint16_t hs;
180 size_t left;
181
182 nl->transmit_ctx = NULL;
183 next = nl->pending;
184 pos = nl->pending;
185 left = size;
186 while (pos != NULL)
187 {
188 hs = (pos->he->hello == NULL) ? 0 : GNUNET_HELLO_size (pos->he->hello);
189 if (left < sizeof (struct InfoMessage) + hs)
190 break;
191 next = pos->next;
192 im.header.size = htons (hs + sizeof (struct InfoMessage));
193 im.header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO);
194 im.trust = htonl (pos->he->trust);
195 im.peer = pos->he->identity;
196 memcpy (&buf[size - left], &im, sizeof (struct InfoMessage));
197 memcpy (&buf[size - left + sizeof (struct InfoMessage)], pos->he->hello, hs);
198 left -= hs + sizeof (struct InfoMessage);
199 GNUNET_free (pos);
200 pos = next;
201 }
202 nl->pending = next;
203 if (nl->pending != NULL)
204 {
205 nl->transmit_ctx
206 = GNUNET_SERVER_notify_transmit_ready (nl->client,
207 sizeof (struct InfoMessage) + hs,
208 GNUNET_TIME_UNIT_FOREVER_REL,
209 &transmit_pending_notification,
210 nl);
211 }
212 return size - left;
213}
214
215
216
217/**
218 * Notify client about host change. Checks if the
219 * respective host entry is already in the list of things
220 * to send to the client, and if not, adds it. Also
221 * triggers a new request for transmission if the pending
222 * list was previously empty.
223 *
224 * @param nl client to notify
225 * @param he entry to notify about
226 */
227static void
228do_notify (struct NotifyList *nl,
229 struct HostEntry *he)
230{
231 struct PendingEntry *pe;
232 uint16_t hsize;
233
234 pe = nl->pending;
235 while (NULL != pe)
236 {
237 if (pe->he == he)
238 return; /* already in list */
239 pe = pe->next;
240 }
241 pe = GNUNET_malloc (sizeof (struct PendingEntry));
242 pe->next = nl->pending;
243 pe->he = he;
244 nl->pending = pe;
245 if (nl->transmit_ctx != NULL)
246 return; /* already trying to transmit */
247 hsize = (he->hello == NULL) ? 0 : GNUNET_HELLO_size (he->hello);
248 nl->transmit_ctx = GNUNET_SERVER_notify_transmit_ready (nl->client,
249 sizeof (struct InfoMessage) + hsize,
250 GNUNET_TIME_UNIT_FOREVER_REL,
251 &transmit_pending_notification,
252 nl);
253}
254
255
256/**
257 * Notify all clients in the notify list about the 113 * Notify all clients in the notify list about the
258 * given host entry changing. 114 * given host entry changing.
259 */ 115 */
260static void 116static struct InfoMessage *
261notify_all (struct HostEntry *he) 117make_info_message (const struct HostEntry *he)
262{ 118{
263 struct NotifyList *nl; 119 struct InfoMessage *im;
264 120 size_t hs;
265 nl = notify_list; 121
266 while (NULL != nl) 122 hs = (he->hello == NULL) ? 0 : GNUNET_HELLO_size (he->hello);
267 { 123 im = GNUNET_malloc (sizeof (struct InfoMessage) + hs);
268 do_notify (nl, he); 124 im->header.size = htons (hs + sizeof (struct InfoMessage));
269 nl = nl->next; 125 im->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_INFO);
270 } 126 im->trust = htonl (he->trust);
127 im->peer = he->identity;
128 memcpy (&im[1], he->hello, hs);
129 return im;
271} 130}
272 131
273 132
@@ -328,6 +187,7 @@ get_trust_filename (const struct GNUNET_PeerIdentity *id)
328 return fn; 187 return fn;
329} 188}
330 189
190
331/** 191/**
332 * Find the host entry for the given peer. Call 192 * Find the host entry for the given peer. Call
333 * only when synchronized! 193 * only when synchronized!
@@ -348,6 +208,25 @@ lookup_host_entry (const struct GNUNET_PeerIdentity *id)
348 208
349 209
350/** 210/**
211 * Broadcast information about the given entry to all
212 * clients that care.
213 *
214 * @param entry entry to broadcast about
215 */
216static void
217notify_all (struct HostEntry *entry)
218{
219 struct InfoMessage *msg;
220
221 msg = make_info_message (entry);
222 GNUNET_SERVER_notification_context_broadcast (notify_list,
223 &msg->header,
224 GNUNET_NO);
225 GNUNET_free (msg);
226}
227
228
229/**
351 * Add a host to the list. 230 * Add a host to the list.
352 * 231 *
353 * @param identity the identity of the host 232 * @param identity the identity of the host
@@ -451,7 +330,7 @@ change_host_trust (const struct GNUNET_PeerIdentity *hostId, int value)
451 host->trust += value; 330 host->trust += value;
452 } 331 }
453 if (host->trust != old_trust) 332 if (host->trust != old_trust)
454 notify_all (host); 333 notify_all (host);
455 return value; 334 return value;
456} 335}
457 336
@@ -834,18 +713,20 @@ handle_notify (void *cls,
834 struct GNUNET_SERVER_Client *client, 713 struct GNUNET_SERVER_Client *client,
835 const struct GNUNET_MessageHeader *message) 714 const struct GNUNET_MessageHeader *message)
836{ 715{
837 struct NotifyList *nl; 716 struct InfoMessage *msg;
838 struct HostEntry *pos; 717 struct HostEntry *pos;
839 718
840 nl = GNUNET_malloc (sizeof (struct NotifyList)); 719 GNUNET_SERVER_notification_context_add (notify_list,
841 nl->next = notify_list; 720 client);
842 nl->client = client;
843 GNUNET_SERVER_client_keep (client);
844 notify_list = nl;
845 pos = hosts; 721 pos = hosts;
846 while (NULL != pos) 722 while (NULL != pos)
847 { 723 {
848 do_notify (nl, pos); 724 msg = make_info_message (pos);
725 GNUNET_SERVER_notification_context_unicast (notify_list,
726 client,
727 &msg->header,
728 GNUNET_NO);
729 GNUNET_free (msg);
849 pos = pos->next; 730 pos = pos->next;
850 } 731 }
851} 732}
@@ -868,48 +749,17 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = {
868 749
869 750
870/** 751/**
871 * Function that is called when a client disconnects. 752 * Clean up our state. Called during shutdown.
753 *
754 * @param cls unused
755 * @param tc scheduler task context, unused
872 */ 756 */
873static void 757static void
874notify_disconnect (void *cls, 758shutdown_task (void *cls,
875 struct GNUNET_SERVER_Client *client) 759 const struct GNUNET_SCHEDULER_TaskContext *tc)
876{ 760{
877 struct NotifyList *pos; 761 GNUNET_SERVER_notification_context_destroy (notify_list);
878 struct NotifyList *prev; 762 notify_list = NULL;
879 struct NotifyList *next;
880 struct PendingEntry *p;
881
882 pos = notify_list;
883 prev = NULL;
884 while (pos != NULL)
885 {
886 next = pos->next;
887 if (pos->client == client)
888 {
889 while (NULL != (p = pos->pending))
890 {
891 pos->pending = p->next;
892 GNUNET_free (p);
893 }
894 if (pos->transmit_ctx != NULL)
895 {
896 GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->transmit_ctx);
897 pos->transmit_ctx = NULL;
898 }
899 if (prev == NULL)
900 notify_list = next;
901 else
902 prev->next = next;
903 GNUNET_SERVER_client_drop (client);
904 GNUNET_free (pos);
905 }
906 else
907 {
908 prev = pos;
909 }
910 pos = next;
911 }
912
913} 763}
914 764
915 765
@@ -927,6 +777,7 @@ run (void *cls,
927 struct GNUNET_SERVER_Handle *server, 777 struct GNUNET_SERVER_Handle *server,
928 const struct GNUNET_CONFIGURATION_Handle *cfg) 778 const struct GNUNET_CONFIGURATION_Handle *cfg)
929{ 779{
780 notify_list = GNUNET_SERVER_notification_context_create (server, 0);
930 GNUNET_assert (GNUNET_OK == 781 GNUNET_assert (GNUNET_OK ==
931 GNUNET_CONFIGURATION_get_value_filename (cfg, 782 GNUNET_CONFIGURATION_get_value_filename (cfg,
932 "peerinfo", 783 "peerinfo",
@@ -948,7 +799,9 @@ run (void *cls,
948 GNUNET_SCHEDULER_add_with_priority (sched, 799 GNUNET_SCHEDULER_add_with_priority (sched,
949 GNUNET_SCHEDULER_PRIORITY_IDLE, 800 GNUNET_SCHEDULER_PRIORITY_IDLE,
950 &cron_clean_data_hosts, NULL); 801 &cron_clean_data_hosts, NULL);
951 GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, NULL); 802 GNUNET_SCHEDULER_add_delayed (sched,
803 GNUNET_TIME_UNIT_FOREVER_REL,
804 &shutdown_task, NULL);
952 GNUNET_SERVER_add_handlers (server, handlers); 805 GNUNET_SERVER_add_handlers (server, handlers);
953} 806}
954 807