pidgin: 16ad73ea: Add P2Pv2 parsing and saving functions. ...

qulogic at pidgin.im qulogic at pidgin.im
Thu Mar 10 01:31:13 EST 2011


----------------------------------------------------------------------
Revision: 16ad73ea13c1d56b4f01acd8cd39d482c8680b28
Parent:   63e9e38a8f31aacc71a9acc074933e484bbfc43e
Author:   qulogic at pidgin.im
Date:     03/10/11 01:29:00
Branch:   im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/16ad73ea13c1d56b4f01acd8cd39d482c8680b28

Changelog: 

Add P2Pv2 parsing and saving functions. Tested by compiling them!
They aren't enabled yet, so we should still be doing v1 right now.

Changes against parent 63e9e38a8f31aacc71a9acc074933e484bbfc43e

  patched  libpurple/protocols/msn/p2p.c
  patched  libpurple/protocols/msn/p2p.h
  patched  libpurple/protocols/msn/tlv.c
  patched  libpurple/protocols/msn/tlv.h

-------------- next part --------------
============================================================
--- libpurple/protocols/msn/p2p.h	7f31a2cfa43e749fcacef6c97cc8d2e5af5d9165
+++ libpurple/protocols/msn/p2p.h	71c7598cb4e37109ea7ce9ba5d27ab4664fc35e0
@@ -50,6 +50,13 @@ typedef struct {
 	guint8  opcode;
 	guint16 message_len;
 	guint32 base_id;
+	GSList *header_tlv;
+	guint8  data_header_len;
+	guint8  data_tf;
+	guint16 package_number;
+	guint32 session_id;
+	GSList *data_tlv;
+/*	guint8  body[1]; */
 } MsnP2Pv2Header;
 
 typedef struct
@@ -103,6 +110,13 @@ typedef enum
 	P2P_APPID_DISPLAY   = 0xC         /**< Display Image */
 } MsnP2PAppId;
 
+typedef enum
+{
+	P2P_OPCODE_NONE = 0x00,
+	P2P_OPCODE_SYN  = 0x01,
+	P2P_OPCODE_RAK  = 0x02
+} MsnP2Pv2OpCode;
+
 MsnP2PInfo *
 msn_p2p_info_new(MsnP2PVersion version);
 
============================================================
--- libpurple/protocols/msn/p2p.c	4f05f9c7de080441e57aea118ac3f568f043061d
+++ libpurple/protocols/msn/p2p.c	4191219d7c75b7feca61b944dc83227741be685a
@@ -26,6 +26,7 @@
 #include "debug.h"
 
 #include "p2p.h"
+#include "tlv.h"
 #include "msnutils.h"
 
 MsnP2PInfo *
@@ -58,8 +59,13 @@ msn_p2p_info_dup(MsnP2PInfo *info)
 
 	switch (info->version) {
 		case MSN_P2P_VERSION_ONE:
+			*new_info = *info;
+			break;
+
 		case MSN_P2P_VERSION_TWO:
 			*new_info = *info;
+			new_info->header.v2.header_tlv = msn_tlvlist_copy(info->header.v2.header_tlv);
+			new_info->header.v2.data_tlv = msn_tlvlist_copy(info->header.v2.data_tlv);
 			break;
 
 		default:
@@ -76,8 +82,12 @@ msn_p2p_info_free(MsnP2PInfo *info)
 {
 	switch (info->version) {
 		case MSN_P2P_VERSION_ONE:
+			/* Nothing to do! */
+			break;
+
 		case MSN_P2P_VERSION_TWO:
-			/* Nothing to do! */
+			msn_tlvlist_free(info->header.v2.header_tlv);
+			msn_tlvlist_free(info->header.v2.data_tlv);
 			break;
 
 		default:
@@ -116,8 +126,47 @@ msn_p2p_header_from_wire(MsnP2PInfo *inf
 			break;
 		}
 
-		case MSN_P2P_VERSION_TWO:
+		case MSN_P2P_VERSION_TWO: {
+			MsnP2Pv2Header *header = &info->header.v2;
+
+			header->header_len = msn_pop8(wire);
+			header->opcode = msn_pop8(wire);
+			header->message_len = msn_pop16be(wire);
+			header->base_id = msn_pop32be(wire);
+			if (header->header_len + header->message_len + P2P_PACKET_FOOTER_SIZE > max_len) {
+				/* Invalid header and data length */
+				len = 0;
+				break;
+			}
+
+			if (header->header_len > 8) {
+				header->header_tlv = msn_tlvlist_read(wire, header->header_len - 8);
+				wire += header->header_len - 8;
+			}
+
+			if (header->message_len > 0) {
+				/* Parse Data packet */
+
+				header->data_header_len = msn_pop8(wire);
+				if (header->data_header_len > header->message_len) {
+					/* Invalid data header length */
+					len = 0;
+					break;
+				}
+				header->data_tf = msn_pop8(wire);
+				header->package_number = msn_pop16be(wire);
+				header->session_id = msn_pop32be(wire);
+
+				if (header->data_header_len > 8) {
+					header->data_tlv = msn_tlvlist_read(wire, header->data_header_len - 8);
+					wire += header->data_header_len - 8;
+				}
+			}
+
+			len = header->header_len + header->message_len;
+
 			break;
+		}
 
 		default:
 			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
@@ -153,11 +202,46 @@ msn_p2p_header_to_wire(MsnP2PInfo *info,
 			break;
 		}
 
-		case MSN_P2P_VERSION_TWO:
+		case MSN_P2P_VERSION_TWO: {
+			MsnP2Pv2Header *header = &info->header.v2;
+
+			if (header->header_tlv != NULL)
+				header->header_len = msn_tlvlist_size(header->header_tlv) + 8;
+			else
+				header->header_len = 8;
+
+			if (header->data_tlv != NULL)
+				header->data_header_len = msn_tlvlist_size(header->data_tlv) + 8;
+			else
+				header->data_header_len = 8;
+
+			tmp = wire = g_new(char, header->header_len + header->data_header_len);
+
+			msn_push8(tmp, header->header_len);
+			msn_push8(tmp, header->opcode);
+			msn_push16be(tmp, header->data_header_len + header->message_len);
+			msn_push32be(tmp, header->base_id);
+
+			if (header->header_tlv != NULL) {
+				msn_tlvlist_write(tmp, header->header_len - 8, header->header_tlv);
+				tmp += header->header_len - 8;
+			}
+
+			msn_push8(tmp, header->data_header_len);
+			msn_push8(tmp, header->data_tf);
+			msn_push16be(tmp, header->package_number);
+			msn_push32be(tmp, header->session_id);
+
+			if (header->data_tlv != NULL) {
+				msn_tlvlist_write(tmp, header->data_header_len - 8, header->data_tlv);
+				tmp += header->data_header_len - 8;
+			}
+
 			if (len)
-				*len = 0;
+				*len = header->header_len + header->data_header_len;
 
 			break;
+		}
 
 		default:
 			purple_debug_error("msn", "Invalid P2P Info version: %d\n", info->version);
============================================================
--- libpurple/protocols/msn/tlv.c	7cd1b7f5716448c2bbd7fc07284e6304b504f3ad
+++ libpurple/protocols/msn/tlv.c	d82a1c8eab5c36339c61ac5a6537e4a9dd298f2e
@@ -46,7 +46,7 @@ static GSList *
 }
 
 static GSList *
-msn_tlv_read(GSList *list, char *bs, size_t *bs_len)
+msn_tlv_read(GSList *list, const char *bs, size_t *bs_len)
 {
 	guint8 type, length;
 	msn_tlv_t *tlv;
@@ -76,7 +76,7 @@ GSList *
 }
 
 GSList *
-msn_tlvlist_read(char *bs, size_t bs_len)
+msn_tlvlist_read(const char *bs, size_t bs_len)
 {
 	GSList *list = NULL;
 
@@ -302,10 +302,10 @@ msn_tlvlist_remove(GSList **list, const 
 	}
 }
 
-#if 0
 int
-msn_tlvlist_write(ByteStream *bs, GSList **list)
+msn_tlvlist_write(char *bs, size_t bs_len, GSList *list)
 {
+#if 0
 	int goodbuflen;
 	GSList *cur;
 	msn_tlv_t *tlv;
@@ -325,9 +325,9 @@ msn_tlvlist_write(ByteStream *bs, GSList
 			byte_stream_putraw(bs, tlv->value, tlv->length);
 	}
 
-	return 1; /* TODO: This is a nonsensical return */
+#endif
+	return 0; /* TODO: This is a nonsensical return */
 }
-#endif
 
 msn_tlv_t *
 msn_tlv_gettlv(GSList *list, const guint16 type, const int nth)
============================================================
--- libpurple/protocols/msn/tlv.h	cadf74a53e49d08f9e82338b7f8f6d8219afe7df
+++ libpurple/protocols/msn/tlv.h	ae315629b373f87b18d8acc905411279fe736b29
@@ -46,13 +46,13 @@ guint32 msn_tlv_get32(GSList *list, cons
 guint32 msn_tlv_get32(GSList *list, const guint16 type, const int nth);
 
 /* TLV list handling functions */
-GSList *msn_tlvlist_read(char *bs, size_t bs_len);
+GSList *msn_tlvlist_read(const char *bs, size_t bs_len);
 GSList *msn_tlvlist_copy(GSList *orig);
 
 int msn_tlvlist_count(GSList *list);
 size_t msn_tlvlist_size(GSList *list);
 gboolean msn_tlvlist_equal(GSList *one, GSList *two);
-int msn_tlvlist_write(char *bs, size_t bs_len, GSList **list);
+int msn_tlvlist_write(char *bs, size_t bs_len, GSList *list);
 void msn_tlvlist_free(GSList *list);
 
 int msn_tlvlist_add_raw(GSList **list, const guint16 type, const guint16 length, const char *value);


More information about the Commits mailing list