Mercurial > pidgin
comparison libpurple/protocols/msn/slplink.c @ 31558:ce968e115c95
propagate from branch 'im.pidgin.cpw.masca.p2p' (head 33ca865dacb9e5bcf763d06f6a42cbaca337cc64)
to branch 'im.pidgin.pidgin' (head 92f47f4e8b0cbb107fd97e1ab814d1cedbf109ad)
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Fri, 06 May 2011 06:25:14 +0000 |
parents | 8cf9270acf4c |
children | 50ca9e64186b |
comparison
equal
deleted
inserted
replaced
31557:f021d93a1f9b | 31558:ce968e115c95 |
---|---|
279 | 279 |
280 void | 280 void |
281 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | 281 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) |
282 { | 282 { |
283 MsnSlpMessagePart *part; | 283 MsnSlpMessagePart *part; |
284 MsnP2PInfo *info; | |
284 long long real_size; | 285 long long real_size; |
285 size_t len = 0; | 286 size_t len = 0; |
287 guint64 offset; | |
286 | 288 |
287 /* Maybe we will want to create a new msg for this slpmsg instead of | 289 /* Maybe we will want to create a new msg for this slpmsg instead of |
288 * reusing the same one all the time. */ | 290 * reusing the same one all the time. */ |
289 part = msn_slpmsgpart_new(slpmsg->header, slpmsg->footer); | 291 info = slpmsg->p2p_info; |
292 part = msn_slpmsgpart_new(msn_p2p_info_dup(info)); | |
290 part->ack_data = slpmsg; | 293 part->ack_data = slpmsg; |
291 | 294 |
292 real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size; | 295 real_size = (msn_p2p_info_get_flags(info) == P2P_ACK) ? 0 : slpmsg->size; |
293 | 296 |
294 if (slpmsg->header->offset < real_size) | 297 offset = msn_p2p_info_get_offset(info); |
298 if (offset < real_size) | |
295 { | 299 { |
296 if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND && | 300 if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND && |
297 purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) | 301 purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) |
298 { | 302 { |
299 len = MIN(MSN_SBCONN_MAX_SIZE, slpmsg->slpcall->u.outgoing.len); | 303 len = MIN(MSN_SBCONN_MAX_SIZE, slpmsg->slpcall->u.outgoing.len); |
300 msn_slpmsgpart_set_bin_data(part, slpmsg->slpcall->u.outgoing.data, len); | 304 msn_slpmsgpart_set_bin_data(part, slpmsg->slpcall->u.outgoing.data, len); |
301 } | 305 } |
302 else | 306 else |
303 { | 307 { |
304 len = slpmsg->size - slpmsg->header->offset; | 308 len = slpmsg->size - offset; |
305 | 309 |
306 if (len > MSN_SBCONN_MAX_SIZE) | 310 if (len > MSN_SBCONN_MAX_SIZE) |
307 len = MSN_SBCONN_MAX_SIZE; | 311 len = MSN_SBCONN_MAX_SIZE; |
308 | 312 |
309 msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + slpmsg->header->offset, len); | 313 msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + offset, len); |
310 } | 314 } |
311 | 315 |
312 slpmsg->header->length = len; | 316 msn_p2p_info_set_length(slpmsg->p2p_info, len); |
313 } | 317 } |
314 | 318 |
315 #if 0 | 319 #if 0 |
316 /* TODO: port this function to SlpMessageParts */ | 320 /* TODO: port this function to SlpMessageParts */ |
317 if (purple_debug_is_verbose()) | 321 if (purple_debug_is_verbose()) |
324 | 328 |
325 slpmsg->parts = g_list_append(slpmsg->parts, part); | 329 slpmsg->parts = g_list_append(slpmsg->parts, part); |
326 msn_slplink_send_part(slplink, part); | 330 msn_slplink_send_part(slplink, part); |
327 | 331 |
328 | 332 |
329 if (msn_p2p_msg_is_data(slpmsg->header->flags) && | 333 if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(info)) && |
330 (slpmsg->slpcall != NULL)) | 334 (slpmsg->slpcall != NULL)) |
331 { | 335 { |
332 slpmsg->slpcall->progress = TRUE; | 336 slpmsg->slpcall->progress = TRUE; |
333 | 337 |
334 if (slpmsg->slpcall->progress_cb != NULL) | 338 if (slpmsg->slpcall->progress_cb != NULL) |
335 { | 339 { |
336 slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, | 340 slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, |
337 len, slpmsg->header->offset); | 341 len, offset); |
338 } | 342 } |
339 } | 343 } |
340 | 344 |
341 /* slpmsg->offset += len; */ | 345 /* slpmsg->offset += len; */ |
342 } | 346 } |
343 | 347 |
344 static void | 348 static void |
345 msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | 349 msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) |
346 { | 350 { |
347 slpmsg = slpmsg; | 351 MsnP2PInfo *info; |
348 slpmsg->footer = g_new0(MsnP2PFooter, 1); | 352 guint32 flags; |
349 | 353 |
350 if (slpmsg->header->flags == P2P_NO_FLAG) | 354 info = slpmsg->p2p_info; |
351 { | 355 |
352 slpmsg->header->ack_id = rand() % 0xFFFFFF00; | 356 flags = msn_p2p_info_get_flags(info); |
353 } | 357 if (flags == P2P_NO_FLAG) |
354 else if (msn_p2p_msg_is_data(slpmsg->header->flags)) | 358 { |
359 msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00); | |
360 } | |
361 else if (msn_p2p_msg_is_data(flags)) | |
355 { | 362 { |
356 MsnSlpCall *slpcall; | 363 MsnSlpCall *slpcall; |
357 slpcall = slpmsg->slpcall; | 364 slpcall = slpmsg->slpcall; |
358 | 365 |
359 g_return_if_fail(slpcall != NULL); | 366 g_return_if_fail(slpcall != NULL); |
360 slpmsg->header->session_id = slpcall->session_id; | 367 msn_p2p_info_set_session_id(info, slpcall->session_id); |
361 slpmsg->footer->value = slpcall->app_id; | 368 msn_p2p_info_set_app_id(info, slpcall->app_id); |
362 slpmsg->header->ack_id = rand() % 0xFFFFFF00; | 369 msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00); |
363 } | 370 } |
364 | 371 |
365 slpmsg->header->id = slpmsg->id; | 372 msn_p2p_info_set_id(info, slpmsg->id); |
366 | 373 |
367 slpmsg->header->total_size = slpmsg->size; | 374 msn_p2p_info_set_total_size(info, slpmsg->size); |
368 | 375 |
369 msn_slplink_send_msgpart(slplink, slpmsg); | 376 msn_slplink_send_msgpart(slplink, slpmsg); |
370 } | 377 } |
371 | 378 |
372 void | 379 void |
398 msn_slplink_release_slpmsg(slplink, slpmsg); | 405 msn_slplink_release_slpmsg(slplink, slpmsg); |
399 } | 406 } |
400 } | 407 } |
401 | 408 |
402 static MsnSlpMessage * | 409 static MsnSlpMessage * |
403 msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PHeader *header) | 410 msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PInfo *info) |
404 { | 411 { |
405 MsnSlpMessage *slpmsg; | 412 MsnSlpMessage *slpmsg; |
406 | 413 |
407 slpmsg = msn_slpmsg_ack_new(header); | 414 slpmsg = msn_slpmsg_ack_new(info); |
408 msn_slpmsg_set_slplink(slpmsg, slplink); | 415 msn_slpmsg_set_slplink(slpmsg, slplink); |
409 | 416 |
410 return slpmsg; | 417 return slpmsg; |
411 } | 418 } |
412 | 419 |
413 static void | 420 static void |
414 msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PHeader *header) | 421 msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PInfo *info) |
415 { | 422 { |
416 MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, header); | 423 MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, info); |
417 | 424 |
418 msn_slplink_send_slpmsg(slplink, slpmsg); | 425 msn_slplink_send_slpmsg(slplink, slpmsg); |
419 msn_slpmsg_destroy(slpmsg); | 426 msn_slpmsg_destroy(slpmsg); |
420 } | 427 } |
421 | 428 |
426 | 433 |
427 for (e = slplink->slp_msgs; e != NULL; e = e->next) | 434 for (e = slplink->slp_msgs; e != NULL; e = e->next) |
428 { | 435 { |
429 MsnSlpMessage *slpmsg = e->data; | 436 MsnSlpMessage *slpmsg = e->data; |
430 | 437 |
431 if ((slpmsg->header->session_id == session_id) && (slpmsg->id == id)) | 438 if ((msn_p2p_info_get_session_id(slpmsg->p2p_info) == session_id) && (slpmsg->id == id)) |
432 return slpmsg; | 439 return slpmsg; |
433 } | 440 } |
434 | 441 |
435 return NULL; | 442 return NULL; |
436 } | 443 } |
437 | 444 |
438 static MsnSlpMessage * | 445 static MsnSlpMessage * |
439 init_first_msg(MsnSlpLink *slplink, MsnP2PHeader *header) | 446 init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info) |
440 { | 447 { |
441 MsnSlpMessage *slpmsg; | 448 MsnSlpMessage *slpmsg; |
449 guint32 session_id; | |
450 guint32 flags; | |
442 | 451 |
443 slpmsg = msn_slpmsg_new(slplink); | 452 slpmsg = msn_slpmsg_new(slplink); |
444 slpmsg->id = header->id; | 453 slpmsg->id = msn_p2p_info_get_id(info); |
445 slpmsg->header->session_id = header->session_id; | 454 session_id = msn_p2p_info_get_session_id(info); |
446 slpmsg->size = header->total_size; | 455 msn_p2p_info_set_session_id(slpmsg->p2p_info, session_id); |
447 slpmsg->header->flags = header->flags; | 456 slpmsg->size = msn_p2p_info_get_total_size(info); |
448 | 457 flags = msn_p2p_info_get_flags(info); |
449 if (slpmsg->header->session_id) | 458 msn_p2p_info_set_flags(slpmsg->p2p_info, flags); |
450 { | 459 |
451 slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->header->session_id); | 460 if (session_id) |
461 { | |
462 slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id); | |
452 if (slpmsg->slpcall != NULL) | 463 if (slpmsg->slpcall != NULL) |
453 { | 464 { |
454 if (msn_p2p_msg_is_data(header->flags)) | 465 if (msn_p2p_msg_is_data(flags)) |
455 { | 466 { |
456 PurpleXfer *xfer = slpmsg->slpcall->xfer; | 467 PurpleXfer *xfer = slpmsg->slpcall->xfer; |
457 if (xfer != NULL) | 468 if (xfer != NULL) |
458 { | 469 { |
459 slpmsg->ft = TRUE; | 470 slpmsg->ft = TRUE; |
486 | 497 |
487 return slpmsg; | 498 return slpmsg; |
488 } | 499 } |
489 | 500 |
490 static void | 501 static void |
491 process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PHeader *header) | 502 process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PInfo *info) |
492 { | 503 { |
493 MsnSlpCall *slpcall; | 504 MsnSlpCall *slpcall; |
505 guint32 flags; | |
494 | 506 |
495 slpcall = msn_slp_process_msg(slplink, slpmsg); | 507 slpcall = msn_slp_process_msg(slplink, slpmsg); |
496 | 508 |
497 if (slpcall == NULL) { | 509 if (slpcall == NULL) { |
498 msn_slpmsg_destroy(slpmsg); | 510 msn_slpmsg_destroy(slpmsg); |
499 return; | 511 return; |
500 } | 512 } |
501 | 513 |
502 purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n"); | 514 purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n"); |
503 | 515 |
504 if (/* !slpcall->wasted && */ slpmsg->header->flags == P2P_DC_HANDSHAKE) | 516 flags = msn_p2p_info_get_flags(slpmsg->p2p_info); |
505 { | 517 |
506 #if 0 | 518 if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP || |
507 MsnDirectConn *directconn; | 519 msn_p2p_msg_is_data(flags)) |
508 | |
509 directconn = slplink->directconn; | |
510 if (!directconn->acked) | |
511 msn_directconn_send_handshake(directconn); | |
512 #endif | |
513 } | |
514 else if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP || | |
515 msn_p2p_msg_is_data(slpmsg->header->flags)) | |
516 { | 520 { |
517 /* Release all the messages and send the ACK */ | 521 /* Release all the messages and send the ACK */ |
518 | 522 |
519 if (slpcall->wait_for_socket) { | 523 if (slpcall->wait_for_socket) { |
520 /* | 524 /* |
523 * invitation before ACK but the listening socket isn't | 527 * invitation before ACK but the listening socket isn't |
524 * created yet. | 528 * created yet. |
525 */ | 529 */ |
526 purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n"); | 530 purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n"); |
527 | 531 |
528 slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header); | 532 slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, info); |
529 } else if (!slpcall->wasted) { | 533 } else if (!slpcall->wasted) { |
530 purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n"); | 534 purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n"); |
531 | 535 |
532 msn_slplink_send_ack(slplink, header); | 536 msn_slplink_send_ack(slplink, info); |
533 msn_slplink_send_queued_slpmsgs(slplink); | 537 msn_slplink_send_queued_slpmsgs(slplink); |
534 } | 538 } |
535 } | 539 } |
536 | 540 |
537 msn_slpmsg_destroy(slpmsg); | 541 msn_slpmsg_destroy(slpmsg); |
547 slpmsg->slpcall->u.incoming_data = | 551 slpmsg->slpcall->u.incoming_data = |
548 g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)part->buffer, part->size); | 552 g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)part->buffer, part->size); |
549 purple_xfer_prpl_ready(slpmsg->slpcall->xfer); | 553 purple_xfer_prpl_ready(slpmsg->slpcall->xfer); |
550 } | 554 } |
551 else if (slpmsg->size && slpmsg->buffer) { | 555 else if (slpmsg->size && slpmsg->buffer) { |
552 if (G_MAXSIZE - part->size < part->header->offset | 556 guint64 offset = msn_p2p_info_get_offset(part->info); |
553 || (part->header->offset + part->size) > slpmsg->size | 557 if (G_MAXSIZE - part->size < offset |
554 || slpmsg->header->offset != part->header->offset) { | 558 || (offset + part->size) > slpmsg->size |
559 || msn_p2p_info_get_offset(slpmsg->p2p_info) != offset) { | |
555 purple_debug_error("msn", | 560 purple_debug_error("msn", |
556 "Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n", | 561 "Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n", |
557 slpmsg->size, part->header->offset, part->size); | 562 slpmsg->size, offset, part->size); |
558 g_return_if_reached(); | 563 g_return_if_reached(); |
559 } else { | 564 } else { |
560 memcpy(slpmsg->buffer + part->header->offset, part->buffer, part->size); | 565 memcpy(slpmsg->buffer + offset, part->buffer, part->size); |
561 slpmsg->header->offset += part->size; | 566 msn_p2p_info_set_offset(slpmsg->p2p_info, offset + part->size); |
562 } | 567 } |
563 } | 568 } |
564 } | 569 } |
565 | 570 |
566 void | 571 void |
567 msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpMessagePart *part) | 572 msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpMessagePart *part) |
568 { | 573 { |
569 MsnSlpMessage *slpmsg; | 574 MsnSlpMessage *slpmsg; |
570 MsnP2PHeader *header; | 575 MsnP2PInfo *info; |
571 guint64 offset; | 576 guint64 offset; |
572 | 577 |
573 header = part->header; | 578 info = part->info; |
574 | 579 |
575 if (header->total_size < header->length) | 580 if (!msn_p2p_info_is_valid(info)) |
576 { | 581 { |
577 /* We seem to have received a bad header */ | 582 /* We seem to have received a bad header */ |
578 purple_debug_warning("msn", "Total size listed in SLP binary header " | 583 purple_debug_warning("msn", "Total size listed in SLP binary header " |
579 "was less than length of this particular message. This " | 584 "was less than length of this particular message. This " |
580 "should not happen. Dropping message.\n"); | 585 "should not happen. Dropping message.\n"); |
581 return; | 586 return; |
582 } | 587 } |
583 | 588 |
584 offset = header->offset; | 589 offset = msn_p2p_info_get_offset(info); |
585 | 590 |
586 if (offset == 0) | 591 if (offset == 0) |
587 slpmsg = init_first_msg(slplink, header); | 592 slpmsg = init_first_msg(slplink, info); |
588 else { | 593 else { |
589 slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id); | 594 guint32 session_id, id; |
595 session_id = msn_p2p_info_get_session_id(info); | |
596 id = msn_p2p_info_get_id(info); | |
597 slpmsg = msn_slplink_message_find(slplink, session_id, id); | |
590 if (slpmsg == NULL) | 598 if (slpmsg == NULL) |
591 { | 599 { |
592 /* Probably the transfer was cancelled */ | 600 /* Probably the transfer was cancelled */ |
593 purple_debug_error("msn", "Couldn't find slpmsg\n"); | 601 purple_debug_error("msn", "Couldn't find slpmsg\n"); |
594 return; | 602 return; |
595 } | 603 } |
596 } | 604 } |
597 | 605 |
598 slpmsg_add_part(slpmsg, part); | 606 slpmsg_add_part(slpmsg, part); |
599 | 607 |
600 | 608 if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(slpmsg->p2p_info)) && |
601 if (msn_p2p_msg_is_data(slpmsg->header->flags) && | |
602 (slpmsg->slpcall != NULL)) | 609 (slpmsg->slpcall != NULL)) |
603 { | 610 { |
604 slpmsg->slpcall->progress = TRUE; | 611 slpmsg->slpcall->progress = TRUE; |
605 | 612 |
606 if (slpmsg->slpcall->progress_cb != NULL) | 613 if (slpmsg->slpcall->progress_cb != NULL) |
614 if (slpmsg->buffer == NULL) | 621 if (slpmsg->buffer == NULL) |
615 return; | 622 return; |
616 #endif | 623 #endif |
617 | 624 |
618 /* All the pieces of the slpmsg have been received */ | 625 /* All the pieces of the slpmsg have been received */ |
619 if (header->offset + header->length >= header->total_size) | 626 if (msn_p2p_info_is_final(info)) |
620 process_complete_msg(slplink, slpmsg, header); | 627 process_complete_msg(slplink, slpmsg, info); |
621 | 628 |
622 /* NOTE: The slpmsg will be destroyed in process_complete_msg or left in | 629 /* NOTE: The slpmsg will be destroyed in process_complete_msg or left in |
623 the slplink until fully received. Don't free it here! | 630 the slplink until fully received. Don't free it here! |
624 */ | 631 */ |
625 } | 632 } |