Mercurial > pidgin.yaz
comparison libpurple/protocols/msn/directconn.c @ 31291:c7fa7c7aca7d
propagate from branch 'im.pidgin.pidgin' (head 51236278b5344e58692ae671bd25a862058432da)
to branch 'im.pidgin.soc.2010.msn-tlc' (head 66d24d59ff5f0bbb624616fad1519de153eeb3cd)
author | masca@cpw.pidgin.im |
---|---|
date | Mon, 19 Jul 2010 21:05:06 +0000 |
parents | f87a1844aff0 74c4aa38adfc |
children | 2d00d29a45fd |
comparison
equal
deleted
inserted
replaced
30643:91869ed3ba59 | 31291:c7fa7c7aca7d |
---|---|
19 * | 19 * |
20 * You should have received a copy of the GNU General Public License | 20 * You should have received a copy of the GNU General Public License |
21 * along with this program; if not, write to the Free Software | 21 * along with this program; if not, write to the Free Software |
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
23 */ | 23 */ |
24 | |
25 #include "internal.h" | |
26 #include "cipher.h" | |
27 #include "debug.h" | |
28 | |
24 #include "msn.h" | 29 #include "msn.h" |
25 #include "directconn.h" | 30 #include "directconn.h" |
26 | 31 |
27 #include "slp.h" | 32 #include "slp.h" |
28 #include "slpmsg.h" | 33 #include "slpmsg.h" |
29 | 34 #include "p2p.h" |
30 #pragma pack(push,1) | 35 |
31 typedef struct { | |
32 guint32 session_id; | |
33 guint32 seq_id; | |
34 guint64 offset; | |
35 guint64 total_size; | |
36 guint32 length; | |
37 guint32 flags; | |
38 guint32 ack_id; | |
39 guint32 ack_uid; | |
40 guint64 ack_size; | |
41 /* guint8 body[1]; */ | |
42 } MsnDcContext; | |
43 #pragma pack(pop) | |
44 | |
45 #define DC_PACKET_HEADER_SIZE sizeof(MsnDcContext) | |
46 #define DC_MAX_BODY_SIZE 8*1024 | 36 #define DC_MAX_BODY_SIZE 8*1024 |
47 #define DC_MAX_PACKET_SIZE (DC_PACKET_HEADER_SIZE + DC_MAX_BODY_SIZE) | 37 #define DC_MAX_PACKET_SIZE (P2P_PACKET_HEADER_SIZE + DC_MAX_BODY_SIZE) |
48 | 38 |
49 static void | 39 static void |
50 msn_dc_calculate_nonce_hash(MsnDirectConnNonceType type, | 40 msn_dc_calculate_nonce_hash(MsnDirectConnNonceType type, |
51 const guchar nonce[16], gchar nonce_hash[37]) | 41 const guchar nonce[16], gchar nonce_hash[37]) |
52 { | 42 { |
119 static void | 109 static void |
120 msn_dc_destroy_packet(MsnDirectConnPacket *p) | 110 msn_dc_destroy_packet(MsnDirectConnPacket *p) |
121 { | 111 { |
122 g_free(p->data); | 112 g_free(p->data); |
123 | 113 |
114 #if 0 | |
124 if (p->msg) | 115 if (p->msg) |
125 msn_message_unref(p->msg); | 116 msn_message_unref(p->msg); |
117 #endif | |
118 if (p->part) | |
119 msn_slpmsgpart_unref(p->part); | |
126 | 120 |
127 g_free(p); | 121 g_free(p); |
128 } | 122 } |
129 | 123 |
130 MsnDirectConn * | 124 MsnDirectConn * |
189 | 183 |
190 slplink = dc->slplink; | 184 slplink = dc->slplink; |
191 if (slplink) { | 185 if (slplink) { |
192 slplink->dc = NULL; | 186 slplink->dc = NULL; |
193 if (slplink->swboard == NULL) | 187 if (slplink->swboard == NULL) |
194 msn_slplink_destroy(slplink); | 188 msn_slplink_unref(slplink); |
195 } | 189 } |
196 | 190 |
197 g_free(dc->msg_body); | 191 g_free(dc->msg_body); |
198 | 192 |
199 if (dc->prev_ack) { | 193 if (dc->prev_ack) { |
351 if (slpcall) { | 345 if (slpcall) { |
352 msn_slpcall_session_init(slpcall); | 346 msn_slpcall_session_init(slpcall); |
353 if (queue) { | 347 if (queue) { |
354 while (!g_queue_is_empty(queue)) { | 348 while (!g_queue_is_empty(queue)) { |
355 MsnDirectConnPacket *p = g_queue_pop_head(queue); | 349 MsnDirectConnPacket *p = g_queue_pop_head(queue); |
356 msn_slplink_send_msg(slplink, p->msg); | 350 msn_slplink_send_msgpart(slplink, (MsnSlpMessage*)p->part->ack_data); |
357 msn_dc_destroy_packet(p); | 351 msn_dc_destroy_packet(p); |
358 } | 352 } |
359 g_queue_free(queue); | 353 g_queue_free(queue); |
360 } | 354 } |
361 } | 355 } |
362 msn_slplink_unref(slplink); | 356 msn_slplink_unref(slplink); |
363 } | |
364 | |
365 static void | |
366 msn_dc_parse_binary_header(MsnDirectConn *dc) | |
367 { | |
368 MsnSlpHeader *h; | |
369 MsnDcContext *context; | |
370 | |
371 g_return_if_fail(dc != NULL); | |
372 | |
373 h = &dc->header; | |
374 /* Skip packet size */ | |
375 context = (MsnDcContext *)(dc->in_buffer + 4); | |
376 | |
377 h->session_id = GUINT32_FROM_LE(context->session_id); | |
378 h->id = GUINT32_FROM_LE(context->seq_id); | |
379 h->offset = GUINT64_FROM_LE(context->offset); | |
380 h->total_size = GUINT64_FROM_LE(context->total_size); | |
381 h->length = GUINT32_FROM_LE(context->length); | |
382 h->flags = GUINT32_FROM_LE(context->flags); | |
383 h->ack_id = GUINT32_FROM_LE(context->ack_id); | |
384 h->ack_sub_id = GUINT32_FROM_LE(context->ack_uid); | |
385 h->ack_size = GUINT64_FROM_LE(context->ack_size); | |
386 } | |
387 | |
388 static const gchar * | |
389 msn_dc_serialize_binary_header(MsnDirectConn *dc) { | |
390 MsnSlpHeader *h; | |
391 static MsnDcContext bin_header; | |
392 | |
393 g_return_val_if_fail(dc != NULL, NULL); | |
394 | |
395 h = &dc->header; | |
396 | |
397 bin_header.session_id = GUINT32_TO_LE(h->session_id); | |
398 bin_header.seq_id = GUINT32_TO_LE(h->id); | |
399 bin_header.offset = GUINT64_TO_LE(h->offset); | |
400 bin_header.total_size = GUINT64_TO_LE(h->total_size); | |
401 bin_header.length = GUINT32_TO_LE(h->length); | |
402 bin_header.flags = GUINT32_TO_LE(h->flags); | |
403 bin_header.ack_id = GUINT32_TO_LE(h->ack_id); | |
404 bin_header.ack_uid = GUINT32_TO_LE(h->ack_sub_id); | |
405 bin_header.ack_size = GUINT64_TO_LE(h->ack_size); | |
406 | |
407 return (const gchar *)&bin_header; | |
408 } | 357 } |
409 | 358 |
410 static void | 359 static void |
411 msn_dc_send_cb(gpointer data, gint fd, PurpleInputCondition cond) | 360 msn_dc_send_cb(gpointer data, gint fd, PurpleInputCondition cond) |
412 { | 361 { |
500 static void | 449 static void |
501 msn_dc_send_handshake_with_nonce(MsnDirectConn *dc, MsnDirectConnPacket *p) | 450 msn_dc_send_handshake_with_nonce(MsnDirectConn *dc, MsnDirectConnPacket *p) |
502 { | 451 { |
503 const gchar *h; | 452 const gchar *h; |
504 | 453 |
505 h = msn_dc_serialize_binary_header(dc); | 454 h = (gchar*) msn_p2p_header_to_wire(&dc->header); |
506 memcpy(p->data, h, DC_PACKET_HEADER_SIZE); | 455 |
507 | 456 memcpy(p->data, h, P2P_PACKET_HEADER_SIZE); |
508 memcpy(p->data + offsetof(MsnDcContext, ack_id), dc->nonce, 16); | 457 |
458 memcpy(p->data + offsetof(MsnP2PHeader, ack_id), dc->nonce, 16); | |
509 | 459 |
510 msn_dc_enqueue_packet(dc, p); | 460 msn_dc_enqueue_packet(dc, p); |
511 } | 461 } |
512 | 462 |
513 static void | 463 static void |
514 msn_dc_send_handshake(MsnDirectConn *dc) | 464 msn_dc_send_handshake(MsnDirectConn *dc) |
515 { | 465 { |
516 MsnDirectConnPacket *p; | 466 MsnDirectConnPacket *p; |
517 | 467 |
518 p = msn_dc_new_packet(DC_PACKET_HEADER_SIZE); | 468 p = msn_dc_new_packet(P2P_PACKET_HEADER_SIZE); |
519 | 469 |
520 dc->header.session_id = 0; | 470 dc->header.session_id = 0; |
521 dc->header.id = dc->slpcall->slplink->slp_seq_id++; | 471 dc->header.id = dc->slpcall->slplink->slp_seq_id++; |
522 dc->header.offset = 0; | 472 dc->header.offset = 0; |
523 dc->header.total_size = 0; | 473 dc->header.total_size = 0; |
530 static void | 480 static void |
531 msn_dc_send_handshake_reply(MsnDirectConn *dc) | 481 msn_dc_send_handshake_reply(MsnDirectConn *dc) |
532 { | 482 { |
533 MsnDirectConnPacket *p; | 483 MsnDirectConnPacket *p; |
534 | 484 |
535 p = msn_dc_new_packet(DC_PACKET_HEADER_SIZE); | 485 p = msn_dc_new_packet(P2P_PACKET_HEADER_SIZE); |
536 | 486 |
537 dc->header.id = dc->slpcall->slplink->slp_seq_id++; | 487 dc->header.id = dc->slpcall->slplink->slp_seq_id++; |
538 dc->header.length = 0; | 488 dc->header.length = 0; |
539 | 489 |
540 msn_dc_send_handshake_with_nonce(dc, p); | 490 msn_dc_send_handshake_with_nonce(dc, p); |
544 msn_dc_verify_handshake(MsnDirectConn *dc, guint32 packet_length) | 494 msn_dc_verify_handshake(MsnDirectConn *dc, guint32 packet_length) |
545 { | 495 { |
546 guchar nonce[16]; | 496 guchar nonce[16]; |
547 gchar nonce_hash[37]; | 497 gchar nonce_hash[37]; |
548 | 498 |
549 if (packet_length != DC_PACKET_HEADER_SIZE) | 499 if (packet_length != P2P_PACKET_HEADER_SIZE) |
550 return FALSE; | 500 return FALSE; |
551 | 501 |
552 memcpy(nonce, dc->in_buffer + 4 + offsetof(MsnDcContext, ack_id), 16); | 502 memcpy(nonce, dc->in_buffer + 4 + offsetof(MsnP2PHeader, ack_id), 16); |
553 | 503 |
554 if (dc->nonce_type == DC_NONCE_PLAIN) { | 504 if (dc->nonce_type == DC_NONCE_PLAIN) { |
555 if (memcmp(dc->nonce, nonce, 16) == 0) { | 505 if (memcmp(dc->nonce, nonce, 16) == 0) { |
556 purple_debug_info("msn", | 506 purple_debug_info("msn", |
557 "Nonce from buddy request and nonce from DC attempt match, " | 507 "Nonce from buddy request and nonce from DC attempt match, " |
587 } | 537 } |
588 | 538 |
589 static void | 539 static void |
590 msn_dc_send_packet_cb(MsnDirectConnPacket *p) | 540 msn_dc_send_packet_cb(MsnDirectConnPacket *p) |
591 { | 541 { |
542 if (p->part != NULL && p->part->ack_cb != NULL) | |
543 p->part->ack_cb(p->part, p->part->ack_data); | |
544 } | |
545 | |
546 #if 0 | |
547 static void | |
548 msn_dc_send_packet_cb(MsnDirectConnPacket *p) | |
549 { | |
592 if (p->msg != NULL && p->msg->ack_cb != NULL) | 550 if (p->msg != NULL && p->msg->ack_cb != NULL) |
593 p->msg->ack_cb(p->msg, p->msg->ack_data); | 551 p->msg->ack_cb(p->msg, p->msg->ack_data); |
594 } | 552 } |
595 | 553 |
596 void | 554 void |
597 msn_dc_enqueue_msg(MsnDirectConn *dc, MsnMessage *msg) | 555 msn_dc_enqueue_msg(MsnDirectConn *dc, MsnMessage *msg) |
598 { | 556 { |
599 MsnDirectConnPacket *p; | 557 MsnDirectConnPacket *p; |
600 guint32 length; | 558 guint32 length; |
601 | 559 |
602 length = msg->body_len + DC_PACKET_HEADER_SIZE; | 560 length = msg->body_len + P2P_PACKET_HEADER_SIZE; |
603 p = msn_dc_new_packet(length); | 561 p = msn_dc_new_packet(length); |
604 | 562 |
605 memcpy(p->data, &msg->msnslp_header, DC_PACKET_HEADER_SIZE); | 563 memcpy(p->data, msg->slpmsg->header, P2P_PACKET_HEADER_SIZE); |
606 memcpy(p->data + DC_PACKET_HEADER_SIZE, msg->body, msg->body_len); | 564 memcpy(p->data + P2P_PACKET_HEADER_SIZE, msg->body, msg->body_len); |
607 | 565 |
608 p->sent_cb = msn_dc_send_packet_cb; | 566 p->sent_cb = msn_dc_send_packet_cb; |
609 p->msg = msn_message_ref(msg); | 567 p->msg = msn_message_ref(msg); |
568 | |
569 msn_dc_enqueue_packet(dc, p); | |
570 } | |
571 #endif | |
572 | |
573 void | |
574 msn_dc_enqueue_part(MsnDirectConn *dc, MsnSlpMessagePart *part) | |
575 { | |
576 MsnDirectConnPacket *p; | |
577 guint32 length; | |
578 | |
579 length = part->size + P2P_PACKET_HEADER_SIZE; | |
580 p = msn_dc_new_packet(length); | |
581 | |
582 memcpy(p->data, part->header, P2P_PACKET_HEADER_SIZE); | |
583 memcpy(p->data + P2P_PACKET_HEADER_SIZE, part->buffer, part->size); | |
584 | |
585 p->sent_cb = msn_dc_send_packet_cb; | |
586 p->part = part; | |
610 | 587 |
611 msn_dc_enqueue_packet(dc, p); | 588 msn_dc_enqueue_packet(dc, p); |
612 } | 589 } |
613 | 590 |
614 static int | 591 static int |
651 | 628 |
652 case DC_STATE_ESTABLISHED: | 629 case DC_STATE_ESTABLISHED: |
653 msn_slplink_process_msg( | 630 msn_slplink_process_msg( |
654 dc->slplink, | 631 dc->slplink, |
655 &dc->header, | 632 &dc->header, |
656 dc->in_buffer + 4 + DC_PACKET_HEADER_SIZE, | 633 dc->in_buffer + 4 + P2P_PACKET_HEADER_SIZE, |
657 dc->header.length | 634 dc->header.length |
658 ); | 635 ); |
659 | 636 |
660 /* | 637 /* |
661 if (dc->num_calls == 0) { | 638 if (dc->num_calls == 0) { |
725 /* Wait for the whole packet to arrive */ | 702 /* Wait for the whole packet to arrive */ |
726 if (dc->in_pos < 4 + packet_length) | 703 if (dc->in_pos < 4 + packet_length) |
727 return; | 704 return; |
728 | 705 |
729 if (dc->state != DC_STATE_FOO) { | 706 if (dc->state != DC_STATE_FOO) { |
730 msn_dc_parse_binary_header(dc); | 707 MsnP2PHeader *context; |
708 MsnP2PHeader *h; | |
709 | |
710 /* Skip packet size */ | |
711 context = (MsnP2PHeader *)(dc->in_buffer + 4); | |
712 | |
713 h = msn_p2p_header_from_wire(context); | |
714 memcpy(&dc->header, h, P2P_PACKET_HEADER_SIZE); | |
715 g_free(h); | |
731 } | 716 } |
732 | 717 |
733 switch (msn_dc_process_packet(dc, packet_length)) { | 718 switch (msn_dc_process_packet(dc, packet_length)) { |
734 case DC_PROCESS_CLOSE: | 719 case DC_PROCESS_CLOSE: |
735 return; | 720 return; |