diff options
Diffstat (limited to 'src/chat/chat.c')
-rw-r--r-- | src/chat/chat.c | 564 |
1 files changed, 270 insertions, 294 deletions
diff --git a/src/chat/chat.c b/src/chat/chat.c index 8e35d10b5..1e90a6369 100644 --- a/src/chat/chat.c +++ b/src/chat/chat.c | |||
@@ -148,8 +148,7 @@ struct GNUNET_CHAT_SendReceiptContext | |||
148 | /** | 148 | /** |
149 | * Ask client to send a join request. | 149 | * Ask client to send a join request. |
150 | */ | 150 | */ |
151 | static int | 151 | static int rejoin_room (struct GNUNET_CHAT_Room *chat_room); |
152 | rejoin_room (struct GNUNET_CHAT_Room *chat_room); | ||
153 | 152 | ||
154 | 153 | ||
155 | /** | 154 | /** |
@@ -161,9 +160,7 @@ rejoin_room (struct GNUNET_CHAT_Room *chat_room); | |||
161 | * @return number of bytes written to buf | 160 | * @return number of bytes written to buf |
162 | */ | 161 | */ |
163 | static size_t | 162 | static size_t |
164 | transmit_acknowledge_request (void *cls, | 163 | transmit_acknowledge_request (void *cls, size_t size, void *buf) |
165 | size_t size, | ||
166 | void *buf) | ||
167 | { | 164 | { |
168 | struct GNUNET_CHAT_SendReceiptContext *src = cls; | 165 | struct GNUNET_CHAT_SendReceiptContext *src = cls; |
169 | struct ConfirmationReceiptMessage *receipt; | 166 | struct ConfirmationReceiptMessage *receipt; |
@@ -172,11 +169,11 @@ transmit_acknowledge_request (void *cls, | |||
172 | size_t msg_size; | 169 | size_t msg_size; |
173 | 170 | ||
174 | if (NULL == buf) | 171 | if (NULL == buf) |
175 | { | 172 | { |
176 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 173 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
177 | _("Could not transmit confirmation receipt\n")); | 174 | _("Could not transmit confirmation receipt\n")); |
178 | return 0; | 175 | return 0; |
179 | } | 176 | } |
180 | #if DEBUG_CHAT | 177 | #if DEBUG_CHAT |
181 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 178 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
182 | "Transmitting confirmation receipt to the service\n"); | 179 | "Transmitting confirmation receipt to the service\n"); |
@@ -185,8 +182,7 @@ transmit_acknowledge_request (void *cls, | |||
185 | GNUNET_assert (size >= msg_size); | 182 | GNUNET_assert (size >= msg_size); |
186 | receipt = buf; | 183 | receipt = buf; |
187 | receipt->header.size = htons (msg_size); | 184 | receipt->header.size = htons (msg_size); |
188 | receipt->header.type = | 185 | receipt->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT); |
189 | htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT); | ||
190 | receipt->reserved = htonl (0); | 186 | receipt->reserved = htonl (0); |
191 | receipt->sequence_number = src->received_msg->sequence_number; | 187 | receipt->sequence_number = src->received_msg->sequence_number; |
192 | receipt->reserved2 = htonl (0); | 188 | receipt->reserved2 = htonl (0); |
@@ -196,17 +192,15 @@ transmit_acknowledge_request (void *cls, | |||
196 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | 192 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), |
197 | &receipt->target); | 193 | &receipt->target); |
198 | receipt->author = src->received_msg->sender; | 194 | receipt->author = src->received_msg->sender; |
199 | receipt->purpose.purpose = | 195 | receipt->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT); |
200 | htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT); | ||
201 | receipt->purpose.size = | 196 | receipt->purpose.size = |
202 | htonl (msg_size - | 197 | htonl (msg_size - |
203 | sizeof (struct GNUNET_MessageHeader) - | 198 | sizeof (struct GNUNET_MessageHeader) - |
204 | sizeof (uint32_t) - | 199 | sizeof (uint32_t) - sizeof (struct GNUNET_CRYPTO_RsaSignature)); |
205 | sizeof (struct GNUNET_CRYPTO_RsaSignature)); | ||
206 | msg_len = ntohs (src->received_msg->header.size) - | 200 | msg_len = ntohs (src->received_msg->header.size) - |
207 | sizeof (struct ReceiveNotificationMessage); | 201 | sizeof (struct ReceiveNotificationMessage); |
208 | GNUNET_CRYPTO_hash (&src->received_msg[1], msg_len, &receipt->content); | 202 | GNUNET_CRYPTO_hash (&src->received_msg[1], msg_len, &receipt->content); |
209 | GNUNET_assert (GNUNET_OK == | 203 | GNUNET_assert (GNUNET_OK == |
210 | GNUNET_CRYPTO_rsa_sign (src->chat_room->my_private_key, | 204 | GNUNET_CRYPTO_rsa_sign (src->chat_room->my_private_key, |
211 | &receipt->purpose, | 205 | &receipt->purpose, |
212 | &receipt->signature)); | 206 | &receipt->signature)); |
@@ -244,187 +238,186 @@ process_result (struct GNUNET_CHAT_Room *room, | |||
244 | 238 | ||
245 | size = ntohs (reply->size); | 239 | size = ntohs (reply->size); |
246 | switch (ntohs (reply->type)) | 240 | switch (ntohs (reply->type)) |
247 | { | 241 | { |
248 | case GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION: | 242 | case GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION: |
249 | #if DEBUG_CHAT | 243 | #if DEBUG_CHAT |
250 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a join notification\n"); | 244 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a join notification\n"); |
251 | #endif | 245 | #endif |
252 | if (size < sizeof (struct JoinNotificationMessage)) | 246 | if (size < sizeof (struct JoinNotificationMessage)) |
253 | { | 247 | { |
254 | GNUNET_break (0); | 248 | GNUNET_break (0); |
255 | return; | 249 | return; |
256 | } | 250 | } |
257 | join_msg = (struct JoinNotificationMessage *) reply; | 251 | join_msg = (struct JoinNotificationMessage *) reply; |
258 | meta_len = size - sizeof (struct JoinNotificationMessage); | 252 | meta_len = size - sizeof (struct JoinNotificationMessage); |
259 | meta = | 253 | meta = |
260 | GNUNET_CONTAINER_meta_data_deserialize ((const char *) &join_msg[1], | 254 | GNUNET_CONTAINER_meta_data_deserialize ((const char *) &join_msg[1], |
261 | meta_len); | 255 | meta_len); |
262 | if (NULL == meta) | 256 | if (NULL == meta) |
263 | { | 257 | { |
264 | GNUNET_break (0); | 258 | GNUNET_break (0); |
265 | return; | 259 | return; |
266 | } | 260 | } |
267 | pos = GNUNET_malloc (sizeof (struct MemberList)); | 261 | pos = GNUNET_malloc (sizeof (struct MemberList)); |
268 | pos->meta = meta; | 262 | pos->meta = meta; |
269 | GNUNET_CRYPTO_hash (&join_msg->public_key, | 263 | GNUNET_CRYPTO_hash (&join_msg->public_key, |
270 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | 264 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), |
271 | &pos->id); | 265 | &pos->id); |
272 | GNUNET_PSEUDONYM_add (room->cfg, &pos->id, meta); | 266 | GNUNET_PSEUDONYM_add (room->cfg, &pos->id, meta); |
273 | pos->next = room->members; | 267 | pos->next = room->members; |
274 | room->members = pos; | 268 | room->members = pos; |
275 | if (GNUNET_NO == room->is_joined) | 269 | if (GNUNET_NO == room->is_joined) |
276 | { | 270 | { |
277 | GNUNET_CRYPTO_rsa_key_get_public (room->my_private_key, &pkey); | 271 | GNUNET_CRYPTO_rsa_key_get_public (room->my_private_key, &pkey); |
278 | if (0 == memcmp (&join_msg->public_key, | 272 | if (0 == memcmp (&join_msg->public_key, |
279 | &pkey, | 273 | &pkey, |
280 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) | 274 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) |
281 | { | 275 | { |
282 | room->join_callback (room->join_callback_cls); | 276 | room->join_callback (room->join_callback_cls); |
283 | room->is_joined = GNUNET_YES; | 277 | room->is_joined = GNUNET_YES; |
284 | } | 278 | } |
285 | else | 279 | else |
286 | { | 280 | { |
287 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 281 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
288 | _("The current user must be the the first one joined\n")); | 282 | _("The current user must be the the first one joined\n")); |
289 | GNUNET_break (0); | 283 | GNUNET_break (0); |
290 | return; | 284 | return; |
291 | } | 285 | } |
292 | } | 286 | } |
293 | else | 287 | else |
294 | room->member_list_callback (room->member_list_callback_cls, | 288 | room->member_list_callback (room->member_list_callback_cls, |
295 | meta, &join_msg->public_key, | 289 | meta, &join_msg->public_key, |
296 | ntohl (join_msg->msg_options)); | 290 | ntohl (join_msg->msg_options)); |
297 | break; | 291 | break; |
298 | case GNUNET_MESSAGE_TYPE_CHAT_LEAVE_NOTIFICATION: | 292 | case GNUNET_MESSAGE_TYPE_CHAT_LEAVE_NOTIFICATION: |
299 | #if DEBUG_CHAT | 293 | #if DEBUG_CHAT |
300 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a leave notification\n"); | 294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a leave notification\n"); |
301 | #endif | 295 | #endif |
302 | if (size < sizeof (struct LeaveNotificationMessage)) | 296 | if (size < sizeof (struct LeaveNotificationMessage)) |
303 | { | 297 | { |
304 | GNUNET_break (0); | 298 | GNUNET_break (0); |
305 | return; | 299 | return; |
306 | } | 300 | } |
307 | leave_msg = (struct LeaveNotificationMessage *) reply; | 301 | leave_msg = (struct LeaveNotificationMessage *) reply; |
308 | room->member_list_callback (room->member_list_callback_cls, | 302 | room->member_list_callback (room->member_list_callback_cls, |
309 | NULL, &leave_msg->user, | 303 | NULL, &leave_msg->user, |
310 | GNUNET_CHAT_MSG_OPTION_NONE); | 304 | GNUNET_CHAT_MSG_OPTION_NONE); |
311 | GNUNET_CRYPTO_hash (&leave_msg->user, | 305 | GNUNET_CRYPTO_hash (&leave_msg->user, |
312 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | 306 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), |
313 | &id); | 307 | &id); |
314 | prev = NULL; | 308 | prev = NULL; |
315 | pos = room->members; | 309 | pos = room->members; |
316 | while ((NULL != pos) && | 310 | while ((NULL != pos) && |
317 | (0 != memcmp (&pos->id, &id, sizeof (GNUNET_HashCode)))) | 311 | (0 != memcmp (&pos->id, &id, sizeof (GNUNET_HashCode)))) |
318 | { | 312 | { |
319 | prev = pos; | 313 | prev = pos; |
320 | pos = pos->next; | 314 | pos = pos->next; |
321 | } | 315 | } |
322 | GNUNET_assert (NULL != pos); | 316 | GNUNET_assert (NULL != pos); |
323 | if (NULL == prev) | 317 | if (NULL == prev) |
324 | room->members = pos->next; | 318 | room->members = pos->next; |
325 | else | 319 | else |
326 | prev->next = pos->next; | 320 | prev->next = pos->next; |
327 | GNUNET_CONTAINER_meta_data_destroy (pos->meta); | 321 | GNUNET_CONTAINER_meta_data_destroy (pos->meta); |
328 | GNUNET_free (pos); | 322 | GNUNET_free (pos); |
329 | break; | 323 | break; |
330 | case GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION: | 324 | case GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION: |
331 | #if DEBUG_CHAT | 325 | #if DEBUG_CHAT |
332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a message notification\n"); | 326 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a message notification\n"); |
333 | #endif | 327 | #endif |
334 | if (size <= sizeof (struct ReceiveNotificationMessage)) | 328 | if (size <= sizeof (struct ReceiveNotificationMessage)) |
335 | { | 329 | { |
336 | GNUNET_break (0); | 330 | GNUNET_break (0); |
337 | return; | 331 | return; |
338 | } | 332 | } |
339 | received_msg = (struct ReceiveNotificationMessage *) reply; | 333 | received_msg = (struct ReceiveNotificationMessage *) reply; |
340 | if (0 != | 334 | if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ACKNOWLEDGED)) |
341 | (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ACKNOWLEDGED)) | 335 | { |
342 | { | 336 | src = GNUNET_malloc (sizeof (struct GNUNET_CHAT_SendReceiptContext)); |
343 | src = GNUNET_malloc (sizeof (struct GNUNET_CHAT_SendReceiptContext)); | 337 | src->chat_room = room; |
344 | src->chat_room = room; | 338 | src->received_msg = GNUNET_memdup (received_msg, size); |
345 | src->received_msg = GNUNET_memdup (received_msg, size); | 339 | GNUNET_CLIENT_notify_transmit_ready (room->client, |
346 | GNUNET_CLIENT_notify_transmit_ready (room->client, | 340 | sizeof (struct |
347 | sizeof (struct ConfirmationReceiptMessage), | 341 | ConfirmationReceiptMessage), |
348 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 342 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
349 | GNUNET_YES, | 343 | GNUNET_YES, |
350 | &transmit_acknowledge_request, | 344 | &transmit_acknowledge_request, src); |
351 | src); | 345 | } |
352 | } | 346 | msg_len = size - sizeof (struct ReceiveNotificationMessage); |
353 | msg_len = size - sizeof (struct ReceiveNotificationMessage); | 347 | if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_PRIVATE)) |
354 | if (0 != | 348 | { |
355 | (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_PRIVATE)) | 349 | if (-1 == GNUNET_CRYPTO_rsa_decrypt (room->my_private_key, |
356 | { | 350 | &received_msg->encrypted_key, |
357 | if (-1 == GNUNET_CRYPTO_rsa_decrypt (room->my_private_key, | 351 | &key, |
358 | &received_msg->encrypted_key, | 352 | sizeof (struct |
359 | &key, | 353 | GNUNET_CRYPTO_AesSessionKey))) |
360 | sizeof (struct GNUNET_CRYPTO_AesSessionKey))) | 354 | { |
361 | { | 355 | GNUNET_break (0); |
362 | GNUNET_break (0); | 356 | return; |
363 | return; | 357 | } |
364 | } | 358 | msg_len = GNUNET_CRYPTO_aes_decrypt (&received_msg[1], |
365 | msg_len = GNUNET_CRYPTO_aes_decrypt (&received_msg[1], | 359 | msg_len, |
366 | msg_len, | 360 | &key, |
367 | &key, | 361 | (const struct |
368 | (const struct GNUNET_CRYPTO_AesInitializationVector *) INITVALUE, | 362 | GNUNET_CRYPTO_AesInitializationVector |
369 | decrypted_msg); | 363 | *) INITVALUE, decrypted_msg); |
370 | message_content = decrypted_msg; | 364 | message_content = decrypted_msg; |
371 | } | 365 | } |
372 | else | 366 | else |
373 | { | 367 | { |
374 | message_content = GNUNET_malloc (msg_len + 1); | 368 | message_content = GNUNET_malloc (msg_len + 1); |
375 | memcpy (message_content, &received_msg[1], msg_len); | 369 | memcpy (message_content, &received_msg[1], msg_len); |
376 | } | 370 | } |
377 | message_content[msg_len] = '\0'; | 371 | message_content[msg_len] = '\0'; |
378 | if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)) | 372 | if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)) |
379 | { | 373 | { |
380 | sender = NULL; | 374 | sender = NULL; |
381 | meta = NULL; | 375 | meta = NULL; |
382 | } | 376 | } |
383 | else | 377 | else |
384 | { | 378 | { |
385 | pos = room->members; | 379 | pos = room->members; |
386 | while ((NULL != pos) && | 380 | while ((NULL != pos) && |
387 | (0 != memcmp (&pos->id, | 381 | (0 != memcmp (&pos->id, |
388 | &received_msg->sender, | 382 | &received_msg->sender, sizeof (GNUNET_HashCode)))) |
389 | sizeof (GNUNET_HashCode)))) | ||
390 | pos = pos->next; | 383 | pos = pos->next; |
391 | GNUNET_assert (NULL != pos); | 384 | GNUNET_assert (NULL != pos); |
392 | sender = &received_msg->sender; | 385 | sender = &received_msg->sender; |
393 | meta = pos->meta; | 386 | meta = pos->meta; |
394 | } | 387 | } |
395 | room->message_callback (room->message_callback_cls, | 388 | room->message_callback (room->message_callback_cls, |
396 | room, | 389 | room, |
397 | sender, | 390 | sender, |
398 | meta, | 391 | meta, |
399 | message_content, | 392 | message_content, |
400 | GNUNET_TIME_absolute_ntoh (received_msg->timestamp), | 393 | GNUNET_TIME_absolute_ntoh (received_msg->timestamp), |
401 | ntohl (received_msg->msg_options)); | 394 | ntohl (received_msg->msg_options)); |
402 | if (message_content != decrypted_msg) | 395 | if (message_content != decrypted_msg) |
403 | GNUNET_free (message_content); | 396 | GNUNET_free (message_content); |
404 | break; | 397 | break; |
405 | case GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION: | 398 | case GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION: |
406 | #if DEBUG_CHAT | 399 | #if DEBUG_CHAT |
407 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a confirmation receipt\n"); | 400 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a confirmation receipt\n"); |
408 | #endif | 401 | #endif |
409 | if (size < sizeof (struct ConfirmationReceiptMessage)) | 402 | if (size < sizeof (struct ConfirmationReceiptMessage)) |
410 | { | 403 | { |
411 | GNUNET_break (0); | 404 | GNUNET_break (0); |
412 | return; | 405 | return; |
413 | } | ||
414 | receipt = (struct ConfirmationReceiptMessage *) reply; | ||
415 | if (NULL != room->confirmation_callback) | ||
416 | room->confirmation_callback (room->confirmation_cls, | ||
417 | room, | ||
418 | ntohl (receipt->sequence_number), | ||
419 | GNUNET_TIME_absolute_ntoh (receipt->timestamp), | ||
420 | &receipt->target); | ||
421 | break; | ||
422 | default: | ||
423 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
424 | _("Unknown message type: '%u'\n"), ntohs (reply->type)); | ||
425 | GNUNET_break_op (0); | ||
426 | break; | ||
427 | } | 406 | } |
407 | receipt = (struct ConfirmationReceiptMessage *) reply; | ||
408 | if (NULL != room->confirmation_callback) | ||
409 | room->confirmation_callback (room->confirmation_cls, | ||
410 | room, | ||
411 | ntohl (receipt->sequence_number), | ||
412 | GNUNET_TIME_absolute_ntoh | ||
413 | (receipt->timestamp), &receipt->target); | ||
414 | break; | ||
415 | default: | ||
416 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
417 | _("Unknown message type: '%u'\n"), ntohs (reply->type)); | ||
418 | GNUNET_break_op (0); | ||
419 | break; | ||
420 | } | ||
428 | } | 421 | } |
429 | 422 | ||
430 | 423 | ||
@@ -435,9 +428,8 @@ process_result (struct GNUNET_CHAT_Room *room, | |||
435 | * @param cls closure, pointer to the 'struct GNUNET_CHAT_Room' | 428 | * @param cls closure, pointer to the 'struct GNUNET_CHAT_Room' |
436 | * @param msg message received, NULL on timeout or fatal error | 429 | * @param msg message received, NULL on timeout or fatal error |
437 | */ | 430 | */ |
438 | static void | 431 | static void |
439 | receive_results (void *cls, | 432 | receive_results (void *cls, const struct GNUNET_MessageHeader *msg) |
440 | const struct GNUNET_MessageHeader *msg) | ||
441 | { | 433 | { |
442 | struct GNUNET_CHAT_Room *chat_room = cls; | 434 | struct GNUNET_CHAT_Room *chat_room = cls; |
443 | 435 | ||
@@ -447,19 +439,18 @@ receive_results (void *cls, | |||
447 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) | 439 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ())) |
448 | return; | 440 | return; |
449 | if (NULL == msg) | 441 | if (NULL == msg) |
450 | { | 442 | { |
451 | GNUNET_break (0); | 443 | GNUNET_break (0); |
452 | rejoin_room (chat_room); | 444 | rejoin_room (chat_room); |
453 | return; | 445 | return; |
454 | } | 446 | } |
455 | process_result (chat_room, msg); | 447 | process_result (chat_room, msg); |
456 | if (NULL == chat_room->client) | 448 | if (NULL == chat_room->client) |
457 | return; /* fatal error */ | 449 | return; /* fatal error */ |
458 | /* continue receiving */ | 450 | /* continue receiving */ |
459 | GNUNET_CLIENT_receive (chat_room->client, | 451 | GNUNET_CLIENT_receive (chat_room->client, |
460 | &receive_results, | 452 | &receive_results, |
461 | chat_room, | 453 | chat_room, GNUNET_TIME_UNIT_FOREVER_REL); |
462 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
463 | } | 454 | } |
464 | 455 | ||
465 | 456 | ||
@@ -480,30 +471,25 @@ init_private_key (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
480 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initializing private key\n"); | 471 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initializing private key\n"); |
481 | #endif | 472 | #endif |
482 | if (GNUNET_OK != | 473 | if (GNUNET_OK != |
483 | GNUNET_CONFIGURATION_get_value_filename (cfg, | 474 | GNUNET_CONFIGURATION_get_value_filename (cfg, "chat", "HOME", &home)) |
484 | "chat", | 475 | { |
485 | "HOME", | 476 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
486 | &home)) | 477 | _("Configuration option `%s' in section `%s' missing\n"), |
487 | { | 478 | "HOME", "chat"); |
488 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 479 | return NULL; |
489 | _("Configuration option `%s' in section `%s' missing\n"), | 480 | } |
490 | "HOME", | ||
491 | "chat"); | ||
492 | return NULL; | ||
493 | } | ||
494 | GNUNET_DISK_directory_create (home); | 481 | GNUNET_DISK_directory_create (home); |
495 | if (GNUNET_OK != GNUNET_DISK_directory_test (home)) | 482 | if (GNUNET_OK != GNUNET_DISK_directory_test (home)) |
496 | { | 483 | { |
497 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 484 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
498 | _("Failed to access chat home directory `%s'\n"), | 485 | _("Failed to access chat home directory `%s'\n"), home); |
499 | home); | 486 | GNUNET_free (home); |
500 | GNUNET_free (home); | 487 | return NULL; |
501 | return NULL; | 488 | } |
502 | } | ||
503 | /* read or create private key */ | 489 | /* read or create private key */ |
504 | keyfile = | 490 | keyfile = |
505 | GNUNET_malloc (strlen (home) + strlen (NICK_IDENTITY_PREFIX) + | 491 | GNUNET_malloc (strlen (home) + strlen (NICK_IDENTITY_PREFIX) + |
506 | strlen (nick_name) + 2); | 492 | strlen (nick_name) + 2); |
507 | strcpy (keyfile, home); | 493 | strcpy (keyfile, home); |
508 | GNUNET_free (home); | 494 | GNUNET_free (home); |
509 | if (keyfile[strlen (keyfile) - 1] != DIR_SEPARATOR) | 495 | if (keyfile[strlen (keyfile) - 1] != DIR_SEPARATOR) |
@@ -512,11 +498,10 @@ init_private_key (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
512 | strcat (keyfile, nick_name); | 498 | strcat (keyfile, nick_name); |
513 | privKey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); | 499 | privKey = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); |
514 | if (NULL == privKey) | 500 | if (NULL == privKey) |
515 | { | 501 | { |
516 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 502 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
517 | _("Failed to create/open key in file `%s'\n"), | 503 | _("Failed to create/open key in file `%s'\n"), keyfile); |
518 | keyfile); | 504 | } |
519 | } | ||
520 | GNUNET_free (keyfile); | 505 | GNUNET_free (keyfile); |
521 | return privKey; | 506 | return privKey; |
522 | } | 507 | } |
@@ -531,9 +516,7 @@ init_private_key (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
531 | * @return number of bytes written to buf | 516 | * @return number of bytes written to buf |
532 | */ | 517 | */ |
533 | static size_t | 518 | static size_t |
534 | transmit_join_request (void *cls, | 519 | transmit_join_request (void *cls, size_t size, void *buf) |
535 | size_t size, | ||
536 | void *buf) | ||
537 | { | 520 | { |
538 | struct GNUNET_CHAT_Room *chat_room = cls; | 521 | struct GNUNET_CHAT_Room *chat_room = cls; |
539 | struct JoinRequestMessage *join_msg; | 522 | struct JoinRequestMessage *join_msg; |
@@ -544,20 +527,21 @@ transmit_join_request (void *cls, | |||
544 | size_t size_of_join; | 527 | size_t size_of_join; |
545 | 528 | ||
546 | if (NULL == buf) | 529 | if (NULL == buf) |
547 | { | 530 | { |
548 | #if DEBUG_CHAT | 531 | #if DEBUG_CHAT |
549 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
550 | "Could not transmit join request, retrying...\n"); | 533 | "Could not transmit join request, retrying...\n"); |
551 | #endif | 534 | #endif |
552 | rejoin_room (chat_room); | 535 | rejoin_room (chat_room); |
553 | return 0; | 536 | return 0; |
554 | } | 537 | } |
555 | #if DEBUG_CHAT | 538 | #if DEBUG_CHAT |
556 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
557 | "Transmitting join request to the service\n"); | 540 | "Transmitting join request to the service\n"); |
558 | #endif | 541 | #endif |
559 | room_len = strlen (chat_room->room_name); | 542 | room_len = strlen (chat_room->room_name); |
560 | meta_len = GNUNET_CONTAINER_meta_data_get_serialized_size (chat_room->member_info); | 543 | meta_len = |
544 | GNUNET_CONTAINER_meta_data_get_serialized_size (chat_room->member_info); | ||
561 | size_of_join = sizeof (struct JoinRequestMessage) + meta_len + room_len; | 545 | size_of_join = sizeof (struct JoinRequestMessage) + meta_len + room_len; |
562 | GNUNET_assert (size >= size_of_join); | 546 | GNUNET_assert (size >= size_of_join); |
563 | join_msg = buf; | 547 | join_msg = buf; |
@@ -567,7 +551,8 @@ transmit_join_request (void *cls, | |||
567 | join_msg->room_name_len = htons (room_len); | 551 | join_msg->room_name_len = htons (room_len); |
568 | join_msg->reserved = htons (0); | 552 | join_msg->reserved = htons (0); |
569 | join_msg->reserved2 = htonl (0); | 553 | join_msg->reserved2 = htonl (0); |
570 | GNUNET_CRYPTO_rsa_key_get_public (chat_room->my_private_key, &join_msg->public_key); | 554 | GNUNET_CRYPTO_rsa_key_get_public (chat_room->my_private_key, |
555 | &join_msg->public_key); | ||
571 | room = (char *) &join_msg[1]; | 556 | room = (char *) &join_msg[1]; |
572 | memcpy (room, chat_room->room_name, room_len); | 557 | memcpy (room, chat_room->room_name, room_len); |
573 | meta = &room[room_len]; | 558 | meta = &room[room_len]; |
@@ -576,15 +561,13 @@ transmit_join_request (void *cls, | |||
576 | &meta, | 561 | &meta, |
577 | meta_len, | 562 | meta_len, |
578 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL)) | 563 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL)) |
579 | { | 564 | { |
580 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 565 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not serialize metadata\n")); |
581 | _("Could not serialize metadata\n")); | 566 | return 0; |
582 | return 0; | 567 | } |
583 | } | ||
584 | GNUNET_CLIENT_receive (chat_room->client, | 568 | GNUNET_CLIENT_receive (chat_room->client, |
585 | &receive_results, | 569 | &receive_results, |
586 | chat_room, | 570 | chat_room, GNUNET_TIME_UNIT_FOREVER_REL); |
587 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
588 | return size_of_join; | 571 | return size_of_join; |
589 | } | 572 | } |
590 | 573 | ||
@@ -598,15 +581,14 @@ rejoin_room (struct GNUNET_CHAT_Room *chat_room) | |||
598 | size_t size_of_join; | 581 | size_t size_of_join; |
599 | 582 | ||
600 | size_of_join = sizeof (struct JoinRequestMessage) + | 583 | size_of_join = sizeof (struct JoinRequestMessage) + |
601 | GNUNET_CONTAINER_meta_data_get_serialized_size (chat_room->member_info) + | 584 | GNUNET_CONTAINER_meta_data_get_serialized_size (chat_room->member_info) + |
602 | strlen (chat_room->room_name); | 585 | strlen (chat_room->room_name); |
603 | if (NULL == | 586 | if (NULL == |
604 | GNUNET_CLIENT_notify_transmit_ready (chat_room->client, | 587 | GNUNET_CLIENT_notify_transmit_ready (chat_room->client, |
605 | size_of_join, | 588 | size_of_join, |
606 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 589 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
607 | GNUNET_YES, | 590 | GNUNET_YES, |
608 | &transmit_join_request, | 591 | &transmit_join_request, chat_room)) |
609 | chat_room)) | ||
610 | return GNUNET_SYSERR; | 592 | return GNUNET_SYSERR; |
611 | return GNUNET_OK; | 593 | return GNUNET_OK; |
612 | } | 594 | } |
@@ -629,12 +611,12 @@ GNUNET_CHAT_leave_room (struct GNUNET_CHAT_Room *chat_room) | |||
629 | GNUNET_CONTAINER_meta_data_destroy (chat_room->member_info); | 611 | GNUNET_CONTAINER_meta_data_destroy (chat_room->member_info); |
630 | GNUNET_CRYPTO_rsa_key_free (chat_room->my_private_key); | 612 | GNUNET_CRYPTO_rsa_key_free (chat_room->my_private_key); |
631 | while (NULL != chat_room->members) | 613 | while (NULL != chat_room->members) |
632 | { | 614 | { |
633 | pos = chat_room->members; | 615 | pos = chat_room->members; |
634 | chat_room->members = pos->next; | 616 | chat_room->members = pos->next; |
635 | GNUNET_CONTAINER_meta_data_destroy (pos->meta); | 617 | GNUNET_CONTAINER_meta_data_destroy (pos->meta); |
636 | GNUNET_free (pos); | 618 | GNUNET_free (pos); |
637 | } | 619 | } |
638 | GNUNET_free (chat_room); | 620 | GNUNET_free (chat_room); |
639 | } | 621 | } |
640 | 622 | ||
@@ -675,8 +657,7 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
675 | GNUNET_CHAT_MemberListCallback memberCallback, | 657 | GNUNET_CHAT_MemberListCallback memberCallback, |
676 | void *member_cls, | 658 | void *member_cls, |
677 | GNUNET_CHAT_MessageConfirmation confirmationCallback, | 659 | GNUNET_CHAT_MessageConfirmation confirmationCallback, |
678 | void *confirmation_cls, | 660 | void *confirmation_cls, GNUNET_HashCode * me) |
679 | GNUNET_HashCode *me) | ||
680 | { | 661 | { |
681 | struct GNUNET_CHAT_Room *chat_room; | 662 | struct GNUNET_CHAT_Room *chat_room; |
682 | struct GNUNET_CRYPTO_RsaPrivateKey *priv_key; | 663 | struct GNUNET_CRYPTO_RsaPrivateKey *priv_key; |
@@ -696,29 +677,29 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
696 | GNUNET_PSEUDONYM_add (cfg, me, member_info); | 677 | GNUNET_PSEUDONYM_add (cfg, me, member_info); |
697 | client = GNUNET_CLIENT_connect ("chat", cfg); | 678 | client = GNUNET_CLIENT_connect ("chat", cfg); |
698 | if (NULL == client) | 679 | if (NULL == client) |
699 | { | 680 | { |
700 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 681 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
701 | _("Failed to connect to the chat service\n")); | 682 | _("Failed to connect to the chat service\n")); |
702 | return NULL; | 683 | return NULL; |
703 | } | 684 | } |
704 | if (NULL == joinCallback) | 685 | if (NULL == joinCallback) |
705 | { | 686 | { |
706 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 687 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
707 | _("Undefined mandatory parameter: joinCallback\n")); | 688 | _("Undefined mandatory parameter: joinCallback\n")); |
708 | return NULL; | 689 | return NULL; |
709 | } | 690 | } |
710 | if (NULL == messageCallback) | 691 | if (NULL == messageCallback) |
711 | { | 692 | { |
712 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 693 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
713 | _("Undefined mandatory parameter: messageCallback\n")); | 694 | _("Undefined mandatory parameter: messageCallback\n")); |
714 | return NULL; | 695 | return NULL; |
715 | } | 696 | } |
716 | if (NULL == memberCallback) | 697 | if (NULL == memberCallback) |
717 | { | 698 | { |
718 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 699 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
719 | _("Undefined mandatory parameter: memberCallback\n")); | 700 | _("Undefined mandatory parameter: memberCallback\n")); |
720 | return NULL; | 701 | return NULL; |
721 | } | 702 | } |
722 | chat_room = GNUNET_malloc (sizeof (struct GNUNET_CHAT_Room)); | 703 | chat_room = GNUNET_malloc (sizeof (struct GNUNET_CHAT_Room)); |
723 | chat_room->msg_options = msg_options; | 704 | chat_room->msg_options = msg_options; |
724 | chat_room->room_name = GNUNET_strdup (room_name); | 705 | chat_room->room_name = GNUNET_strdup (room_name); |
@@ -737,10 +718,10 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
737 | chat_room->client = client; | 718 | chat_room->client = client; |
738 | chat_room->members = NULL; | 719 | chat_room->members = NULL; |
739 | if (GNUNET_SYSERR == rejoin_room (chat_room)) | 720 | if (GNUNET_SYSERR == rejoin_room (chat_room)) |
740 | { | 721 | { |
741 | GNUNET_CHAT_leave_room (chat_room); | 722 | GNUNET_CHAT_leave_room (chat_room); |
742 | return NULL; | 723 | return NULL; |
743 | } | 724 | } |
744 | return chat_room; | 725 | return chat_room; |
745 | } | 726 | } |
746 | 727 | ||
@@ -754,22 +735,19 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
754 | * @return number of bytes written to buf | 735 | * @return number of bytes written to buf |
755 | */ | 736 | */ |
756 | static size_t | 737 | static size_t |
757 | transmit_send_request (void *cls, | 738 | transmit_send_request (void *cls, size_t size, void *buf) |
758 | size_t size, | ||
759 | void *buf) | ||
760 | { | 739 | { |
761 | struct GNUNET_CHAT_SendMessageContext *smc = cls; | 740 | struct GNUNET_CHAT_SendMessageContext *smc = cls; |
762 | struct TransmitRequestMessage *msg_to_send; | 741 | struct TransmitRequestMessage *msg_to_send; |
763 | size_t msg_size; | 742 | size_t msg_size; |
764 | 743 | ||
765 | if (NULL == buf) | 744 | if (NULL == buf) |
766 | { | 745 | { |
767 | #if DEBUG_CHAT | 746 | #if DEBUG_CHAT |
768 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Could not transmit a chat message\n"); |
769 | "Could not transmit a chat message\n"); | ||
770 | #endif | 748 | #endif |
771 | return 0; | 749 | return 0; |
772 | } | 750 | } |
773 | #if DEBUG_CHAT | 751 | #if DEBUG_CHAT |
774 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 752 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
775 | "Transmitting a chat message to the service\n"); | 753 | "Transmitting a chat message to the service\n"); |
@@ -782,7 +760,7 @@ transmit_send_request (void *cls, | |||
782 | msg_to_send->msg_options = htonl (smc->options); | 760 | msg_to_send->msg_options = htonl (smc->options); |
783 | msg_to_send->sequence_number = htonl (smc->sequence_number); | 761 | msg_to_send->sequence_number = htonl (smc->sequence_number); |
784 | msg_to_send->timestamp = | 762 | msg_to_send->timestamp = |
785 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | 763 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); |
786 | msg_to_send->reserved = htonl (0); | 764 | msg_to_send->reserved = htonl (0); |
787 | if (NULL == smc->receiver) | 765 | if (NULL == smc->receiver) |
788 | memset (&msg_to_send->target, 0, sizeof (GNUNET_HashCode)); | 766 | memset (&msg_to_send->target, 0, sizeof (GNUNET_HashCode)); |
@@ -796,18 +774,18 @@ transmit_send_request (void *cls, | |||
796 | * stored on the service side. | 774 | * stored on the service side. |
797 | */ | 775 | */ |
798 | if (smc->options & GNUNET_CHAT_MSG_AUTHENTICATED) | 776 | if (smc->options & GNUNET_CHAT_MSG_AUTHENTICATED) |
799 | { | 777 | { |
800 | msg_to_send->purpose.purpose = | 778 | msg_to_send->purpose.purpose = |
801 | htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | 779 | htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); |
802 | msg_to_send->purpose.size = | 780 | msg_to_send->purpose.size = |
803 | htonl (msg_size - | 781 | htonl (msg_size - |
804 | sizeof (struct GNUNET_MessageHeader) - | 782 | sizeof (struct GNUNET_MessageHeader) - |
805 | sizeof (struct GNUNET_CRYPTO_RsaSignature)); | 783 | sizeof (struct GNUNET_CRYPTO_RsaSignature)); |
806 | GNUNET_assert (GNUNET_OK == | 784 | GNUNET_assert (GNUNET_OK == |
807 | GNUNET_CRYPTO_rsa_sign (smc->chat_room->my_private_key, | 785 | GNUNET_CRYPTO_rsa_sign (smc->chat_room->my_private_key, |
808 | &msg_to_send->purpose, | 786 | &msg_to_send->purpose, |
809 | &msg_to_send->signature)); | 787 | &msg_to_send->signature)); |
810 | } | 788 | } |
811 | GNUNET_free (smc->message); | 789 | GNUNET_free (smc->message); |
812 | GNUNET_free (smc); | 790 | GNUNET_free (smc); |
813 | return msg_size; | 791 | return msg_size; |
@@ -827,8 +805,8 @@ void | |||
827 | GNUNET_CHAT_send_message (struct GNUNET_CHAT_Room *room, | 805 | GNUNET_CHAT_send_message (struct GNUNET_CHAT_Room *room, |
828 | const char *message, | 806 | const char *message, |
829 | enum GNUNET_CHAT_MsgOptions options, | 807 | enum GNUNET_CHAT_MsgOptions options, |
830 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *receiver, | 808 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded |
831 | uint32_t *sequence_number) | 809 | *receiver, uint32_t * sequence_number) |
832 | { | 810 | { |
833 | size_t msg_size; | 811 | size_t msg_size; |
834 | struct GNUNET_CHAT_SendMessageContext *smc; | 812 | struct GNUNET_CHAT_SendMessageContext *smc; |
@@ -849,9 +827,7 @@ GNUNET_CHAT_send_message (struct GNUNET_CHAT_Room *room, | |||
849 | GNUNET_CLIENT_notify_transmit_ready (room->client, | 827 | GNUNET_CLIENT_notify_transmit_ready (room->client, |
850 | msg_size, | 828 | msg_size, |
851 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 829 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
852 | GNUNET_YES, | 830 | GNUNET_YES, &transmit_send_request, smc); |
853 | &transmit_send_request, | ||
854 | smc); | ||
855 | } | 831 | } |
856 | 832 | ||
857 | /* end of chat.c */ | 833 | /* end of chat.c */ |