# HG changeset patch # User Christian Hammond # Date 1063764637 0 # Node ID ab80de7a74d1bf8ba04af31f552ed0016580719c # Parent 1c4e4c725e0d31db430f5036740791ad658b97af [gaim-migrate @ 7414] Commitinating the current MSNSLP code. It's not working.. I don't know why. No clients will respond to my messages, even though they appear very valid. committer: Tailor Script diff -r 1c4e4c725e0d -r ab80de7a74d1 src/protocols/msn/msg.c --- a/src/protocols/msn/msg.c Wed Sep 17 01:50:15 2003 +0000 +++ b/src/protocols/msn/msg.c Wed Sep 17 02:10:37 2003 +0000 @@ -98,6 +98,35 @@ msg->msnslp_message = TRUE; msg->size += 52; + msn_message_set_flag(msg, 'D'); + msn_message_set_content_type(msg, "application/x-msnmsgrp2p"); + msn_message_set_charset(msg, NULL); + + return msg; +} + +MsnMessage * +msn_message_new_msnslp_ack(MsnMessage *acked_msg) +{ + MsnMessage *msg; + + g_return_val_if_fail(acked_msg != NULL, NULL); + g_return_val_if_fail(acked_msg->msnslp_message, NULL); + + msg = msn_message_new_msnslp(); + + msg->msnslp_ack_message = TRUE; + msg->acked_msg = msn_message_ref(acked_msg); + + msg->msnslp_header.session_id = acked_msg->msnslp_header.session_id; + msg->msnslp_header.total_size_1 = acked_msg->msnslp_header.total_size_1; + msg->msnslp_header.total_size_2 = acked_msg->msnslp_header.total_size_2; + msg->msnslp_header.flags = 0x02; + msg->msnslp_header.ack_session_id = acked_msg->msnslp_header.session_id; + msg->msnslp_header.ack_unique_id = acked_msg->msnslp_header.ack_session_id; + msg->msnslp_header.ack_length_1 = acked_msg->msnslp_header.total_size_1; + msg->msnslp_header.ack_length_2 = acked_msg->msnslp_header.total_size_2; + return msg; } @@ -219,20 +248,26 @@ /* Import the header. */ msg->msnslp_header.session_id = msn_get32(tmp); tmp += 4; msg->msnslp_header.id = msn_get32(tmp); tmp += 4; - msg->msnslp_header.offset = msn_get32(tmp); tmp += 8; - msg->msnslp_header.total_size = msn_get32(tmp); tmp += 8; + msg->msnslp_header.offset_1 = msn_get32(tmp); tmp += 4; + msg->msnslp_header.offset_2 = msn_get32(tmp); tmp += 4; + msg->msnslp_header.total_size_1 = msn_get32(tmp); tmp += 4; + msg->msnslp_header.total_size_2 = msn_get32(tmp); tmp += 4; msg->msnslp_header.length = msn_get32(tmp); tmp += 4; msg->msnslp_header.flags = msn_get32(tmp); tmp += 4; msg->msnslp_header.ack_session_id = msn_get32(tmp); tmp += 4; msg->msnslp_header.ack_unique_id = msn_get32(tmp); tmp += 4; - msg->msnslp_header.ack_length = msn_get32(tmp); tmp += 8; + msg->msnslp_header.ack_length_1 = msn_get32(tmp); tmp += 4; + msg->msnslp_header.ack_length_2 = msn_get32(tmp); tmp += 4; /* Convert to the right endianness */ msg->msnslp_header.session_id = ntohl(msg->msnslp_header.session_id); msg->msnslp_header.id = ntohl(msg->msnslp_header.id); msg->msnslp_header.length = ntohl(msg->msnslp_header.length); msg->msnslp_header.flags = ntohl(msg->msnslp_header.flags); - msg->msnslp_header.ack_length = ntohl(msg->msnslp_header.ack_length); + msg->msnslp_header.ack_length_1 = + ntohl(msg->msnslp_header.ack_length_1); + msg->msnslp_header.ack_length_2 = + ntohl(msg->msnslp_header.ack_length_2); msg->msnslp_header.ack_session_id = ntohl(msg->msnslp_header.ack_session_id); msg->msnslp_header.ack_unique_id = @@ -282,6 +317,9 @@ g_hash_table_destroy(msg->attr_table); g_list_free(msg->attr_list); + if (msg->msnslp_ack_message) + msn_message_unref(msg->acked_msg); + gaim_debug(GAIM_DEBUG_INFO, "msn", "Destroying message\n"); g_free(msg); } @@ -319,7 +357,6 @@ msn_message_to_string(const MsnMessage *msg, size_t *ret_size) { GList *l; - const char *body; char *msg_start; char *str; char buf[MSN_BUF_LEN]; @@ -336,8 +373,6 @@ */ g_return_val_if_fail(msg != NULL, NULL); - body = msn_message_get_body(msg); - if (msn_message_is_incoming(msg)) { MsnUser *sender = msn_message_get_sender(msg); @@ -391,42 +426,63 @@ if (msg->msnslp_message) { char *c; - long session_id, id, offset, total_size, length, flags; - long ack_session_id, ack_unique_id, ack_length; + long session_id, id, offset_1, offset_2, total_size_1, total_size_2; + long length, flags; + long ack_session_id, ack_unique_id, ack_length_1, ack_length_2; c = str + strlen(str); session_id = htonl(msg->msnslp_header.session_id); id = htonl(msg->msnslp_header.id); - offset = htonl(msg->msnslp_header.offset); - total_size = htonl(msg->msnslp_header.total_size); + offset_1 = htonl(msg->msnslp_header.offset_1); + offset_2 = htonl(msg->msnslp_header.offset_2); + total_size_1 = htonl(msg->msnslp_header.total_size_1); + total_size_2 = htonl(msg->msnslp_header.total_size_2); length = htonl(msg->msnslp_header.length); flags = htonl(msg->msnslp_header.flags); ack_session_id = htonl(msg->msnslp_header.ack_session_id); ack_unique_id = htonl(msg->msnslp_header.ack_unique_id); - ack_length = htonl(msg->msnslp_header.ack_length); + ack_length_1 = htonl(msg->msnslp_header.ack_length_1); + ack_length_2 = htonl(msg->msnslp_header.ack_length_2); c += msn_put32(c, session_id); c += msn_put32(c, id); - c += msn_put32(c, offset); - c += msn_put32(c, 0); - c += msn_put32(c, total_size); - c += msn_put32(c, 0); + c += msn_put32(c, offset_1); + c += msn_put32(c, offset_2); + c += msn_put32(c, total_size_1); + c += msn_put32(c, total_size_2); c += msn_put32(c, length); c += msn_put32(c, flags); c += msn_put32(c, ack_session_id); c += msn_put32(c, ack_unique_id); - c += msn_put32(c, ack_length); - c += msn_put32(c, 0); + c += msn_put32(c, ack_length_1); + c += msn_put32(c, ack_length_2); - if (body != NULL) + if (msg->bin_content) { - g_strlcpy(c, body, msg->size - (c - msg_start)); + size_t bin_len; + const void *body = msn_message_get_bin_data(msg, &bin_len); + + if (body != NULL) + { + memcpy(c, body, msg->size - (c - msg_start)); - c += strlen(body); + c += bin_len; + } + } + else + { + const char *body = msn_message_get_body(msg); - if (strlen(body) > 0) - *c++ = '\0'; + if (body != NULL) + { + g_strlcpy(c, body, msg->size - (c - msg_start)); + + c += strlen(body); + + if (strlen(body) > 0) + *c++ = '\0'; + } } c += msn_put32(c, msg->msnslp_footer.app_id); @@ -440,6 +496,8 @@ } else { + const char *body = msn_message_get_body(msg); + g_strlcat(str, body, len); if (msg->size != strlen(msg_start)) { @@ -498,6 +556,9 @@ msg->receiver = user; + if (msg->msnslp_message) + msn_message_set_attr(msg, "P2P-Dest", msn_user_get_passport(user)); + msn_user_ref(msg->receiver); } @@ -552,7 +613,9 @@ size_t new_len; g_return_if_fail(msg != NULL); - g_return_if_fail(body != NULL); + + if (msg->bin_content) + msn_message_set_bin_data(msg, NULL, 0); if (msg->body != NULL) { msg->size -= strlen(msg->body); @@ -562,36 +625,86 @@ msg->size--; } - for (c = body; *c != '\0'; c++) { - if (*c == '\n' && (c == body || *(c - 1) != '\r')) - newline_count++; - } + if (body != NULL) + { + for (c = body; *c != '\0'; c++) + { + if (*c == '\n' && (c == body || *(c - 1) != '\r')) + newline_count++; + } - new_len = strlen(body) + newline_count; + new_len = strlen(body) + newline_count; - buf = g_new0(char, new_len + 1); + buf = g_new0(char, new_len + 1); - for (c = body, d = buf; *c != '\0'; c++) { - if (*c == '\n' && (c == body || *(c - 1) != '\r')) { - *d++ = '\r'; - *d++ = '\n'; + for (c = body, d = buf; *c != '\0'; c++) { + if (*c == '\n' && (c == body || *(c - 1) != '\r')) { + *d++ = '\r'; + *d++ = '\n'; + } + else + *d++ = *c; } - else - *d++ = *c; + + msg->body = buf; + msg->size += new_len; + + msg->bin_content = FALSE; + + if (msg->msnslp_message) + msg->size++; } - - msg->body = buf; - - msg->size += new_len; - - if (msg->msnslp_message) - msg->size++; + else + msg->body = NULL; } const char * msn_message_get_body(const MsnMessage *msg) { g_return_val_if_fail(msg != NULL, NULL); + g_return_val_if_fail(!msg->bin_content, NULL); + + return msg->body; +} + +void +msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len) +{ + g_return_if_fail(msg != NULL); + + if (!msg->bin_content) + msn_message_set_body(msg, NULL); + + msg->bin_content = TRUE; + + if (msg->body != NULL) + { + msg->size -= msg->bin_len; + g_free(msg->body); + } + + if (data != NULL && len > 0) + { + msg->body = g_memdup(data, len); + msg->bin_len = len; + + msg->size += len; + } + else + { + msg->body = NULL; + msg->bin_len = 0; + } +} + +const void * +msn_message_get_bin_data(const MsnMessage *msg, size_t *len) +{ + g_return_val_if_fail(msg != NULL, NULL); + g_return_val_if_fail(len != NULL, NULL); + g_return_val_if_fail(msg->bin_content, NULL); + + *len = msg->bin_len; return msg->body; } diff -r 1c4e4c725e0d -r ab80de7a74d1 src/protocols/msn/msg.h --- a/src/protocols/msn/msg.h Wed Sep 17 01:50:15 2003 +0000 +++ b/src/protocols/msn/msg.h Wed Sep 17 02:10:37 2003 +0000 @@ -31,13 +31,16 @@ { long session_id; long id; - long offset; - long total_size; + long offset_1; + long offset_2; + long total_size_1; + long total_size_2; long length; long flags; long ack_session_id; long ack_unique_id; - long ack_length; + long ack_length_1; + long ack_length_2; } MsnSlpHeader; @@ -55,6 +58,7 @@ size_t ref_count; /**< The reference count. */ gboolean msnslp_message; + gboolean msnslp_ack_message; MsnUser *sender; MsnUser *receiver; @@ -66,12 +70,17 @@ size_t size; + gboolean bin_content; + char *content_type; char *charset; char *body; + size_t bin_len; MsnSlpHeader msnslp_header; MsnSlpFooter msnslp_footer; + + MsnMessage *acked_msg; GHashTable *attr_table; GList *attr_list; @@ -94,6 +103,15 @@ MsnMessage *msn_message_new_msnslp(void); /** + * Creates a MSNSLP ack message. + * + * @param acked_msg The message to acknowledge. + * + * @return A new MSNSLP ack message. + */ +MsnMessage *msn_message_new_msnslp_ack(MsnMessage *acked_msg); + +/** * Creates a new message based off a string. * * @param session The MSN session. @@ -244,6 +262,25 @@ const char *msn_message_get_body(const MsnMessage *msg); /** + * Sets the binary content of the message. + * + * @param msg The message. + * @param data The binary data. + * @param len The length of the data. + */ +void msn_message_set_bin_data(MsnMessage *msg, const void *data, size_t len); + +/** + * Returns the binary content of the message. + * + * @param msg The message. + * @param len The returned length of the data. + * + * @return The binary data. + */ +const void *msn_message_get_bin_data(const MsnMessage *msg, size_t *len); + +/** * Sets the content type in a message. * * @param msg The message. diff -r 1c4e4c725e0d -r ab80de7a74d1 src/protocols/msn/msnslp.c --- a/src/protocols/msn/msnslp.c Wed Sep 17 01:50:15 2003 +0000 +++ b/src/protocols/msn/msnslp.c Wed Sep 17 02:10:37 2003 +0000 @@ -22,25 +22,6 @@ #include "msn.h" #include "msnslp.h" -static void -send_ack(MsnSlpSession *slpsession, MsnMessage *acked_msg) -{ - MsnMessage *msg; - - msg = msn_message_new_msnslp(); - - msg->msnslp_header.length = acked_msg->msnslp_header.length; - msg->msnslp_header.flags = 0x02; - msg->msnslp_header.ack_session_id = - acked_msg->msnslp_header.ack_session_id; - msg->msnslp_header.ack_unique_id = - acked_msg->msnslp_header.id; - msg->msnslp_header.ack_length = acked_msg->msnslp_header.length; - - /* Send this puppy. */ - msn_slp_session_send_msg(slpsession, msg); -} - MsnSlpSession * msn_slp_session_new(MsnSwitchBoard *swboard, gboolean local_initiated) { @@ -86,43 +67,127 @@ } /* Now send an ack, since we got this. */ - send_ack(slpsession, msg); + msn_slp_session_send_ack(slpsession, msg); return FALSE; } +static void +send_msg_part(MsnSlpSession *slpsession, MsnMessage *msg) +{ + msg->msnslp_header.length = + (slpsession->orig_len - slpsession->offset > 1202 + ? 1202 : slpsession->orig_len - slpsession->offset); + + if (slpsession->offset > 0) + { + if (msg->bin_content) + { + msn_message_set_bin_data(msg, + slpsession->orig_body + slpsession->offset, + msg->msnslp_header.length); + } + else + { + msn_message_set_body(msg, + slpsession->orig_body + slpsession->offset); + } + } + + msg->msnslp_header.offset_1 = slpsession->offset; + + msn_switchboard_send_msg(slpsession->swboard, msg); + + if (slpsession->offset + msg->msnslp_header.length == slpsession->orig_len) + { + msn_message_destroy(msg); + + g_free(slpsession->orig_body); + + slpsession->offset = 0; + slpsession->orig_len = 0; + slpsession->orig_body = NULL; + slpsession->outgoing_msg = NULL; + } + else + slpsession->offset += msg->msnslp_header.length; +} + void msn_slp_session_send_msg(MsnSlpSession *slpsession, MsnMessage *msg) { g_return_if_fail(slpsession != NULL); g_return_if_fail(msg != NULL); g_return_if_fail(msg->msnslp_message); + g_return_if_fail(slpsession->outgoing_msg == NULL); msg->msnslp_header.session_id = slpsession->session_id; + slpsession->outgoing_msg = msn_message_ref(msg); + if (slpsession->base_id == 0) { - slpsession->base_id = rand() % 0xFFFFFF00 + 4; + slpsession->base_id = rand() % 0x0FFFFFF0 + 4; slpsession->prev_msg_id = slpsession->base_id; } + else if (slpsession->offset == 0) + slpsession->prev_msg_id = ++slpsession->base_id; + + msg->msnslp_header.id = slpsession->prev_msg_id; +// msg->msnslp_header.ack_session_id = rand() % 0xFFFFFF00; + msg->msnslp_header.ack_session_id = 1980589; + + msn_message_set_charset(msg, NULL); + + if (msg->msnslp_header.session_id != 0) + msg->msnslp_footer.app_id = 1; + + if (msg->bin_content) + { + const void *temp; + + temp = msn_message_get_bin_data(msg, &slpsession->orig_len); + + slpsession->orig_body = g_memdup(temp, slpsession->orig_len); + } + else + { + slpsession->orig_body = g_strdup(msn_message_get_body(msg)); + slpsession->orig_len = strlen(slpsession->orig_body); + } + + msg->msnslp_header.total_size_1 = slpsession->orig_len; + + send_msg_part(slpsession, msg); +} + +void +msn_slp_session_send_ack(MsnSlpSession *slpsession, MsnMessage *acked_msg) +{ + MsnMessage *msg; + gboolean new_base_id = FALSE; + + g_return_if_fail(slpsession != NULL); + g_return_if_fail(acked_msg != NULL); + g_return_if_fail(acked_msg->msnslp_message); + g_return_if_fail(slpsession->outgoing_msg == NULL); + + msg = msn_message_new_msnslp_ack(acked_msg); + + if (slpsession->base_id == 0) + { + slpsession->base_id = rand() % 0x0FFFFE00 + 10; + slpsession->prev_msg_id = slpsession->base_id; + + new_base_id = TRUE; + } else slpsession->prev_msg_id = ++slpsession->base_id; msg->msnslp_header.id = slpsession->prev_msg_id; - msg->msnslp_header.ack_session_id = rand() % 0xFFFFFF00; - if (msn_message_get_body(msg) != NULL) - msg->msnslp_header.total_size = strlen(msn_message_get_body(msg)); - - msn_message_set_charset(msg, NULL); - - msn_message_set_flag(msg, 'D'); - msn_message_set_content_type(msg, "application/x-msnmsgrp2p"); - msn_message_set_attr(msg, "P2P-Dest", - msn_user_get_passport(msn_message_get_receiver(msg))); - - if (msg->msnslp_header.session_id != 0) - msg->msnslp_footer.app_id = 1; + if (new_base_id) + slpsession->prev_msg_id -= 4; msn_switchboard_send_msg(slpsession->swboard, msg); } @@ -141,7 +206,6 @@ char *call_id; char *content; char *body; - char *c; g_return_if_fail(slpsession != NULL); g_return_if_fail(local_user != NULL); @@ -152,8 +216,10 @@ msnobj_base64 = tobase64(msnobj_data, strlen(msnobj_data)); g_free(msnobj_data); +#if 0 if ((c = strchr(msnobj_base64, '=')) != NULL) *c = '\0'; +#endif session_id = rand() % 0xFFFFFF00 + 4; diff -r 1c4e4c725e0d -r ab80de7a74d1 src/protocols/msn/msnslp.h --- a/src/protocols/msn/msnslp.h Wed Sep 17 01:50:15 2003 +0000 +++ b/src/protocols/msn/msnslp.h Wed Sep 17 02:10:37 2003 +0000 @@ -38,6 +38,13 @@ long session_id; long base_id; long prev_msg_id; + + size_t offset; + + void *orig_body; + size_t orig_len; + + MsnMessage *outgoing_msg; }; /** @@ -80,6 +87,15 @@ void msn_slp_session_send_msg(MsnSlpSession *session, MsnMessage *msg); /** + * Sends an acknowledgement message over a MSNSLP session for the + * specified message. + * + * @param slpsession The MSNSLP session to send the acknowledgement over. + * @param acked_msg The message to acknowledge. + */ +void msn_slp_session_send_ack(MsnSlpSession *session, MsnMessage *acked_msg); + +/** * Requests a User Display image over a MSNSLP session. * * @param slpsession The MSNSLP session to request the image over. diff -r 1c4e4c725e0d -r ab80de7a74d1 src/protocols/msn/switchboard.c --- a/src/protocols/msn/switchboard.c Wed Sep 17 01:50:15 2003 +0000 +++ b/src/protocols/msn/switchboard.c Wed Sep 17 02:10:37 2003 +0000 @@ -91,7 +91,7 @@ send_clientcaps(swboard); - if (0 && session->protocol_ver >= 9) + if (session->protocol_ver >= 9) { MsnUser *local_user, *remote_user;