~micahg/ubuntu/natty/pidgin/2.7.9-2

« back to all changes in this revision

Viewing changes to libpurple/protocols/msn/directconn.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-12-02 16:45:52 UTC
  • mfrom: (2.3.14 sid)
  • Revision ID: james.westby@ubuntu.com-20101202164552-z64wykojzacbb546
Tags: 1:2.7.7-1ubuntu1
New upstream version, drop msn workaround

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * along with this program; if not, write to the Free Software
22
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
29
#include "msn.h"
25
30
#include "directconn.h"
26
31
 
27
32
#include "slp.h"
28
33
#include "slpmsg.h"
29
 
 
30
 
#pragma pack(push,1)
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)
 
34
#include "p2p.h"
 
35
 
46
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
39
static void
50
40
msn_dc_calculate_nonce_hash(MsnDirectConnNonceType type,
121
111
{
122
112
        g_free(p->data);
123
113
 
 
114
#if 0
124
115
        if (p->msg)
125
116
                msn_message_unref(p->msg);
 
117
#endif
 
118
        if (p->part)
 
119
                msn_slpmsgpart_unref(p->part);
126
120
 
127
121
        g_free(p);
128
122
}
191
185
        if (slplink) {
192
186
                slplink->dc = NULL;
193
187
                if (slplink->swboard == NULL)
194
 
                        msn_slplink_destroy(slplink);
 
188
                        msn_slplink_unref(slplink);
195
189
        }
196
190
 
197
191
        g_free(dc->msg_body);
353
347
                if (queue) {
354
348
                        while (!g_queue_is_empty(queue)) {
355
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
351
                                msn_dc_destroy_packet(p);
358
352
                        }
359
353
                        g_queue_free(queue);
363
357
}
364
358
 
365
359
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
 
}
409
 
 
410
 
static void
411
360
msn_dc_send_cb(gpointer data, gint fd, PurpleInputCondition cond)
412
361
{
413
362
        MsnDirectConn *dc = data;
502
451
{
503
452
        const gchar *h;
504
453
 
505
 
        h = msn_dc_serialize_binary_header(dc);
506
 
        memcpy(p->data, h, DC_PACKET_HEADER_SIZE);
507
 
 
508
 
        memcpy(p->data + offsetof(MsnDcContext, ack_id), dc->nonce, 16);
 
454
        h = (gchar*)  msn_p2p_header_to_wire(&dc->header);
 
455
 
 
456
        memcpy(p->data, h, P2P_PACKET_HEADER_SIZE);
 
457
 
 
458
        memcpy(p->data + offsetof(MsnP2PHeader, ack_id), dc->nonce, 16);
509
459
 
510
460
        msn_dc_enqueue_packet(dc, p);
511
461
}
515
465
{
516
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
470
        dc->header.session_id = 0;
521
471
        dc->header.id = dc->slpcall->slplink->slp_seq_id++;
532
482
{
533
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
487
        dc->header.id = dc->slpcall->slplink->slp_seq_id++;
538
488
        dc->header.length = 0;
546
496
        guchar nonce[16];
547
497
        gchar  nonce_hash[37];
548
498
 
549
 
        if (packet_length != DC_PACKET_HEADER_SIZE)
 
499
        if (packet_length != P2P_PACKET_HEADER_SIZE)
550
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
504
        if (dc->nonce_type == DC_NONCE_PLAIN) {
555
505
                if (memcmp(dc->nonce, nonce, 16) == 0) {
589
539
static void
590
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
550
        if (p->msg != NULL && p->msg->ack_cb != NULL)
593
551
                p->msg->ack_cb(p->msg, p->msg->ack_data);
594
552
}
599
557
        MsnDirectConnPacket *p;
600
558
        guint32 length;
601
559
 
602
 
        length = msg->body_len + DC_PACKET_HEADER_SIZE;
 
560
        length = msg->body_len + P2P_PACKET_HEADER_SIZE;
603
561
        p = msn_dc_new_packet(length);
604
562
 
605
 
        memcpy(p->data, &msg->msnslp_header, DC_PACKET_HEADER_SIZE);
606
 
        memcpy(p->data + DC_PACKET_HEADER_SIZE, msg->body, msg->body_len);
 
563
        memcpy(p->data, msg->slpmsg->header, P2P_PACKET_HEADER_SIZE);
 
564
        memcpy(p->data + P2P_PACKET_HEADER_SIZE, msg->body, msg->body_len);
607
565
 
608
566
        p->sent_cb = msn_dc_send_packet_cb;
609
567
        p->msg = msn_message_ref(msg);
610
568
 
611
569
        msn_dc_enqueue_packet(dc, p);
612
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;
 
587
 
 
588
        msn_dc_enqueue_packet(dc, p);
 
589
}
613
590
 
614
591
static int
615
592
msn_dc_process_packet(MsnDirectConn *dc, guint32 packet_length)
616
593
{
 
594
        MsnSlpMessagePart *part;
 
595
 
617
596
        g_return_val_if_fail(dc != NULL, DC_PROCESS_ERROR);
618
597
 
619
598
        switch (dc->state) {
650
629
                break;
651
630
 
652
631
        case DC_STATE_ESTABLISHED:
653
 
                msn_slplink_process_msg(
654
 
                        dc->slplink,
655
 
                        &dc->header,
656
 
                        dc->in_buffer + 4 + DC_PACKET_HEADER_SIZE,
657
 
                        dc->header.length
658
 
                );
 
632
 
 
633
                if (dc->header.length) {
 
634
                        part = msn_slpmsgpart_new_from_data(dc->in_buffer + 4, dc->header.length);
 
635
                        msn_slplink_process_msg(dc->slplink, part);
 
636
                        msn_slpmsgpart_destroy(part);
 
637
                }
659
638
 
660
639
                /*
661
640
                if (dc->num_calls == 0) {
727
706
                        return;
728
707
 
729
708
                if (dc->state != DC_STATE_FOO) {
730
 
                        msn_dc_parse_binary_header(dc);
 
709
                        MsnP2PHeader *context;
 
710
                        MsnP2PHeader *h;
 
711
                        
 
712
                        /* Skip packet size */
 
713
                        context = (MsnP2PHeader *)(dc->in_buffer + 4);
 
714
 
 
715
                        h = msn_p2p_header_from_wire(context);
 
716
                        memcpy(&dc->header, h, P2P_PACKET_HEADER_SIZE);
 
717
                        g_free(h);
731
718
                }
732
719
 
733
720
                switch (msn_dc_process_packet(dc, packet_length)) {