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
25
30
#include "directconn.h"
28
33
#include "slpmsg.h"
45
#define DC_PACKET_HEADER_SIZE sizeof(MsnDcContext)
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)
50
40
msn_dc_calculate_nonce_hash(MsnDirectConnNonceType type,
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);
359
353
g_queue_free(queue);
366
msn_dc_parse_binary_header(MsnDirectConn *dc)
369
MsnDcContext *context;
371
g_return_if_fail(dc != NULL);
374
/* Skip packet size */
375
context = (MsnDcContext *)(dc->in_buffer + 4);
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);
389
msn_dc_serialize_binary_header(MsnDirectConn *dc) {
391
static MsnDcContext bin_header;
393
g_return_val_if_fail(dc != NULL, NULL);
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);
407
return (const gchar *)&bin_header;
411
360
msn_dc_send_cb(gpointer data, gint fd, PurpleInputCondition cond)
413
362
MsnDirectConn *dc = data;
505
h = msn_dc_serialize_binary_header(dc);
506
memcpy(p->data, h, DC_PACKET_HEADER_SIZE);
508
memcpy(p->data + offsetof(MsnDcContext, ack_id), dc->nonce, 16);
454
h = (gchar*) msn_p2p_header_to_wire(&dc->header);
456
memcpy(p->data, h, P2P_PACKET_HEADER_SIZE);
458
memcpy(p->data + offsetof(MsnP2PHeader, ack_id), dc->nonce, 16);
510
460
msn_dc_enqueue_packet(dc, p);
546
496
guchar nonce[16];
547
497
gchar nonce_hash[37];
549
if (packet_length != DC_PACKET_HEADER_SIZE)
499
if (packet_length != P2P_PACKET_HEADER_SIZE)
552
memcpy(nonce, dc->in_buffer + 4 + offsetof(MsnDcContext, ack_id), 16);
502
memcpy(nonce, dc->in_buffer + 4 + offsetof(MsnP2PHeader, ack_id), 16);
554
504
if (dc->nonce_type == DC_NONCE_PLAIN) {
555
505
if (memcmp(dc->nonce, nonce, 16) == 0) {
590
540
msn_dc_send_packet_cb(MsnDirectConnPacket *p)
542
if (p->part != NULL && p->part->ack_cb != NULL)
543
p->part->ack_cb(p->part, p->part->ack_data);
548
msn_dc_send_packet_cb(MsnDirectConnPacket *p)
592
550
if (p->msg != NULL && p->msg->ack_cb != NULL)
593
551
p->msg->ack_cb(p->msg, p->msg->ack_data);
599
557
MsnDirectConnPacket *p;
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);
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);
608
566
p->sent_cb = msn_dc_send_packet_cb;
609
567
p->msg = msn_message_ref(msg);
611
569
msn_dc_enqueue_packet(dc, p);
574
msn_dc_enqueue_part(MsnDirectConn *dc, MsnSlpMessagePart *part)
576
MsnDirectConnPacket *p;
579
length = part->size + P2P_PACKET_HEADER_SIZE;
580
p = msn_dc_new_packet(length);
582
memcpy(p->data, part->header, P2P_PACKET_HEADER_SIZE);
583
memcpy(p->data + P2P_PACKET_HEADER_SIZE, part->buffer, part->size);
585
p->sent_cb = msn_dc_send_packet_cb;
588
msn_dc_enqueue_packet(dc, p);
615
592
msn_dc_process_packet(MsnDirectConn *dc, guint32 packet_length)
594
MsnSlpMessagePart *part;
617
596
g_return_val_if_fail(dc != NULL, DC_PROCESS_ERROR);
619
598
switch (dc->state) {
652
631
case DC_STATE_ESTABLISHED:
653
msn_slplink_process_msg(
656
dc->in_buffer + 4 + DC_PACKET_HEADER_SIZE,
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);
661
640
if (dc->num_calls == 0) {
729
708
if (dc->state != DC_STATE_FOO) {
730
msn_dc_parse_binary_header(dc);
709
MsnP2PHeader *context;
712
/* Skip packet size */
713
context = (MsnP2PHeader *)(dc->in_buffer + 4);
715
h = msn_p2p_header_from_wire(context);
716
memcpy(&dc->header, h, P2P_PACKET_HEADER_SIZE);
733
720
switch (msn_dc_process_packet(dc, packet_length)) {