comparison libpurple/protocols/msn/slplink.c @ 30478:0b22c840f4f4

merge of '5378b2067023c1be51d87906196d87f03c9992e3' and 'da604206b18f52b79c03f5cdd11dc0438e46038b'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 07 May 2010 20:04:42 +0000
parents afc9cec164e4 7a82bc59b63f
children 3f6daa187665
comparison
equal deleted inserted replaced
30301:7fbb7612e3dd 30478:0b22c840f4f4
99 return; 99 return;
100 } 100 }
101 101
102 session = slplink->session; 102 session = slplink->session;
103 103
104 #if 0 104 if (slplink->dc != NULL)
105 if (slplink->directconn != NULL) 105 msn_dc_destroy(slplink->dc);
106 msn_directconn_destroy(slplink->directconn);
107 #endif
108 106
109 while (slplink->slp_calls != NULL) 107 while (slplink->slp_calls != NULL)
110 msn_slpcall_destroy(slplink->slp_calls->data); 108 msn_slpcall_destroy(slplink->slp_calls->data);
111 109
112 g_queue_free(slplink->slp_msg_queue); 110 g_queue_free(slplink->slp_msg_queue);
183 { 181 {
184 if (slplink->swboard != NULL) 182 if (slplink->swboard != NULL)
185 slplink->swboard->flag |= MSN_SB_FLAG_FT; 183 slplink->swboard->flag |= MSN_SB_FLAG_FT;
186 184
187 slplink->slp_calls = g_list_append(slplink->slp_calls, slpcall); 185 slplink->slp_calls = g_list_append(slplink->slp_calls, slpcall);
186
187 /*
188 if (slplink->dc != NULL && slplink->dc->state == DC_STATE_ESTABLISHED)
189 msn_dc_ref(slplink->dc);
190 */
188 } 191 }
189 192
190 void 193 void
191 msn_slplink_remove_slpcall(MsnSlpLink *slplink, MsnSlpCall *slpcall) 194 msn_slplink_remove_slpcall(MsnSlpLink *slplink, MsnSlpCall *slpcall)
192 { 195 {
196 /*
197 if (slplink->dc != NULL && slplink->dc->state == DC_STATE_ESTABLISHED)
198 msn_dc_unref(slplink->dc);
199 */
200
193 slplink->slp_calls = g_list_remove(slplink->slp_calls, slpcall); 201 slplink->slp_calls = g_list_remove(slplink->slp_calls, slpcall);
194 202
195 /* The slplink has no slpcalls in it, release it from MSN_SB_FLAG_FT. 203 /* The slplink has no slpcalls in it, release it from MSN_SB_FLAG_FT.
196 * If nothing else is using it then this might cause swboard to be 204 * If nothing else is using it then this might cause swboard to be
197 * destroyed. */ 205 * destroyed. */
198 if (slplink->slp_calls == NULL && slplink->swboard != NULL) 206 if (slplink->slp_calls == NULL && slplink->swboard != NULL)
199 msn_switchboard_release(slplink->swboard, MSN_SB_FLAG_FT); 207 msn_switchboard_release(slplink->swboard, MSN_SB_FLAG_FT);
208
209 /* The slplink has no slpcalls in it, release it from the DC. */
210 if (slplink->slp_calls == NULL && slplink->dc != NULL)
211 msn_dc_destroy(slplink->dc);
200 } 212 }
201 213
202 MsnSlpCall * 214 MsnSlpCall *
203 msn_slplink_find_slp_call(MsnSlpLink *slplink, const char *id) 215 msn_slplink_find_slp_call(MsnSlpLink *slplink, const char *id)
204 { 216 {
237 } 249 }
238 250
239 static void 251 static void
240 msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg) 252 msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg)
241 { 253 {
242 #if 0 254 if (slplink->dc != NULL && slplink->dc->state == DC_STATE_ESTABLISHED)
243 if (slplink->directconn != NULL) 255 {
244 { 256 msn_dc_enqueue_msg(slplink->dc, msg);
245 msn_directconn_send_msg(slplink->directconn, msg);
246 } 257 }
247 else 258 else
248 #endif
249 { 259 {
250 if (slplink->swboard == NULL) 260 if (slplink->swboard == NULL)
251 { 261 {
252 slplink->swboard = msn_session_get_swboard(slplink->session, 262 slplink->swboard = msn_session_get_swboard(slplink->session,
253 slplink->remote_user, MSN_SB_FLAG_FT); 263 slplink->remote_user, MSN_SB_FLAG_FT);
459 { 469 {
460 msn_slplink_release_slpmsg(slplink, slpmsg); 470 msn_slplink_release_slpmsg(slplink, slpmsg);
461 } 471 }
462 } 472 }
463 473
474 static MsnSlpMessage *
475 msn_slplink_create_ack(MsnSlpLink *slplink, MsnSlpHeader *header)
476 {
477 MsnSlpMessage *slpmsg;
478
479 slpmsg = msn_slpmsg_new(slplink);
480
481 slpmsg->session_id = header->session_id;
482 slpmsg->size = header->total_size;
483 slpmsg->flags = 0x02;
484 slpmsg->ack_id = header->id;
485 slpmsg->ack_sub_id = header->ack_id;
486 slpmsg->ack_size = header->total_size;
487 slpmsg->info = "SLP ACK";
488
489 return slpmsg;
490 }
491
464 static void 492 static void
465 msn_slplink_send_ack(MsnSlpLink *slplink, MsnMessage *msg) 493 msn_slplink_send_ack(MsnSlpLink *slplink, MsnSlpHeader *header)
466 { 494 {
467 MsnSlpMessage *slpmsg; 495 MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, header);
468
469 slpmsg = msn_slpmsg_new(slplink);
470
471 slpmsg->session_id = msg->msnslp_header.session_id;
472 slpmsg->size = msg->msnslp_header.total_size;
473 slpmsg->flags = 0x02;
474 slpmsg->ack_id = msg->msnslp_header.id;
475 slpmsg->ack_sub_id = msg->msnslp_header.ack_id;
476 slpmsg->ack_size = msg->msnslp_header.total_size;
477 slpmsg->info = "SLP ACK";
478 496
479 msn_slplink_send_slpmsg(slplink, slpmsg); 497 msn_slplink_send_slpmsg(slplink, slpmsg);
480 msn_slpmsg_destroy(slpmsg); 498 msn_slpmsg_destroy(slpmsg);
481 } 499 }
482 500
519 537
520 return NULL; 538 return NULL;
521 } 539 }
522 540
523 void 541 void
524 msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg) 542 msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpHeader *header, const char *data, gsize len)
525 { 543 {
526 MsnSlpMessage *slpmsg; 544 MsnSlpMessage *slpmsg;
527 const char *data;
528 guint64 offset; 545 guint64 offset;
529 gsize len;
530 PurpleXfer *xfer = NULL; 546 PurpleXfer *xfer = NULL;
531 547
532 if (purple_debug_is_verbose()) 548 if (header->total_size < header->length)
533 msn_slpmsg_show(msg);
534
535 #ifdef MSN_DEBUG_SLP_FILES
536 debug_msg_to_file(msg, FALSE);
537 #endif
538
539 if (msg->msnslp_header.total_size < msg->msnslp_header.length)
540 { 549 {
541 purple_debug_error("msn", "This can't be good\n"); 550 purple_debug_error("msn", "This can't be good\n");
542 g_return_if_reached(); 551 g_return_if_reached();
543 } 552 }
544 553
545 data = msn_message_get_bin_data(msg, &len); 554 offset = header->offset;
546
547 offset = msg->msnslp_header.offset;
548 555
549 if (offset == 0) 556 if (offset == 0)
550 { 557 {
551 slpmsg = msn_slpmsg_new(slplink); 558 slpmsg = msn_slpmsg_new(slplink);
552 slpmsg->id = msg->msnslp_header.id; 559 slpmsg->id = header->id;
553 slpmsg->session_id = msg->msnslp_header.session_id; 560 slpmsg->session_id = header->session_id;
554 slpmsg->size = msg->msnslp_header.total_size; 561 slpmsg->size = header->total_size;
555 slpmsg->flags = msg->msnslp_header.flags; 562 slpmsg->flags = header->flags;
556 563
557 if (slpmsg->session_id) 564 if (slpmsg->session_id)
558 { 565 {
559 if (slpmsg->slpcall == NULL) 566 if (slpmsg->slpcall == NULL)
560 slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id); 567 slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);
595 } 602 }
596 } 603 }
597 } 604 }
598 else 605 else
599 { 606 {
600 slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id); 607 slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id);
601 if (slpmsg == NULL) 608 if (slpmsg == NULL)
602 { 609 {
603 /* Probably the transfer was canceled */ 610 /* Probably the transfer was canceled */
604 purple_debug_error("msn", "Couldn't find slpmsg\n"); 611 purple_debug_error("msn", "Couldn't find slpmsg\n");
605 return; 612 return;
643 #if 0 650 #if 0
644 if (slpmsg->buffer == NULL) 651 if (slpmsg->buffer == NULL)
645 return; 652 return;
646 #endif 653 #endif
647 654
648 if (msg->msnslp_header.offset + msg->msnslp_header.length 655 if (header->offset + header->length >= header->total_size)
649 >= msg->msnslp_header.total_size)
650 { 656 {
651 /* All the pieces of the slpmsg have been received */ 657 /* All the pieces of the slpmsg have been received */
652 MsnSlpCall *slpcall; 658 MsnSlpCall *slpcall;
653 659
654 slpcall = msn_slp_process_msg(slplink, slpmsg); 660 slpcall = msn_slp_process_msg(slplink, slpmsg);
656 if (slpcall == NULL) { 662 if (slpcall == NULL) {
657 msn_slpmsg_destroy(slpmsg); 663 msn_slpmsg_destroy(slpmsg);
658 return; 664 return;
659 } 665 }
660 666
661 if (!slpcall->wasted) { 667 purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n");
662 if (slpmsg->flags == 0x100) 668
663 { 669 if (/* !slpcall->wasted && */ slpmsg->flags == 0x100)
664 MsnDirectConn *directconn; 670 {
665
666 directconn = slplink->directconn;
667 #if 0 671 #if 0
668 if (!directconn->acked) 672 MsnDirectConn *directconn;
669 msn_directconn_send_handshake(directconn); 673
674 directconn = slplink->directconn;
675 if (!directconn->acked)
676 msn_directconn_send_handshake(directconn);
670 #endif 677 #endif
671 } 678 }
672 else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 || 679 else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 ||
673 slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || 680 slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 ||
674 slpmsg->flags == 0x1000030) 681 slpmsg->flags == 0x1000030)
675 { 682 {
676 /* Release all the messages and send the ACK */ 683 /* Release all the messages and send the ACK */
677 684
678 msn_slplink_send_ack(slplink, msg); 685 if (slpcall->wait_for_socket) {
686 /*
687 * Save ack for later because we have to send
688 * a 200 OK message to the previous direct connect
689 * invitation before ACK but the listening socket isn't
690 * created yet.
691 */
692 purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n");
693
694 slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header);
695 } else if (!slpcall->wasted) {
696 purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n");
697
698 msn_slplink_send_ack(slplink, header);
679 msn_slplink_send_queued_slpmsgs(slplink); 699 msn_slplink_send_queued_slpmsgs(slplink);
680 } 700 }
681
682 } 701 }
683 702
684 msn_slpmsg_destroy(slpmsg); 703 msn_slpmsg_destroy(slpmsg);
685 704
686 if (slpcall->wasted) 705 if (!slpcall->wait_for_socket && slpcall->wasted)
687 msn_slpcall_destroy(slpcall); 706 msn_slpcall_destroy(slpcall);
688 } 707 }
689 } 708 }
690 709
691 static gchar * 710 static gchar *