protected override void SendOnePacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage p2pMessage) { if (remote == null) { return; } string to = ((int)remote.ClientType).ToString() + ":" + remote.Account; string from = ((int)NSMessageHandler.Owner.ClientType).ToString() + ":" + NSMessageHandler.Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = NSMessageHandler.MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.To][MIMERoutingHeaders.EPID] = remoteGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.ServiceChannel] = "PE"; mmMessage.RoutingHeaders[MIMERoutingHeaders.Options] = "0"; mmMessage.ContentKeyVersion = "2.0"; SLPMessage slpMessage = p2pMessage.IsSLPData ? p2pMessage.InnerMessage as SLPMessage : null; if (slpMessage != null && ((slpMessage.ContentType == "application/x-msnmsgr-transreqbody" || slpMessage.ContentType == "application/x-msnmsgr-transrespbody" || slpMessage.ContentType == "application/x-msnmsgr-transdestaddrupdate"))) { mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.SignalP2P; mmMessage.InnerBody = slpMessage.GetBytes(false); mmMessage.InnerMessage = slpMessage; } else { mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/x-msnmsgrp2p"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentTransferEncoding] = "binary"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.Data; //mmMessage.ContentHeaders[MIMEContentHeaders.Pipe] = PackageNo.ToString(); mmMessage.ContentHeaders[MIMEContentHeaders.BridgingOffsets] = "0"; mmMessage.InnerBody = p2pMessage.GetBytes(true); mmMessage.InnerMessage = p2pMessage; } NSMessageProcessor nsmp = (NSMessageProcessor)NSMessageHandler.MessageProcessor; int transId = nsmp.IncreaseTransactionID(); lock (p2pAckMessages) p2pAckMessages[transId] = new P2PMessageSessionEventArgs(p2pMessage, session); NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.TransactionID = transId; sdgPayload.InnerMessage = mmMessage; nsmp.SendMessage(sdgPayload, sdgPayload.TransactionID); }
protected override void SendMultiPacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage[] sendList) { if (remote == null) { return; } NSMessageProcessor nsmp = (NSMessageProcessor)NSMessageHandler.MessageProcessor; string to = ((int)remote.ClientType).ToString() + ":" + remote.Account; string from = ((int)NSMessageHandler.Owner.ClientType).ToString() + ":" + NSMessageHandler.Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = NSMessageHandler.MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.To][MIMERoutingHeaders.EPID] = remoteGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.ServiceChannel] = "PE"; mmMessage.RoutingHeaders[MIMERoutingHeaders.Options] = "0"; mmMessage.ContentKeyVersion = "2.0"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/x-msnmsgrp2p"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentTransferEncoding] = "binary"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.Data; List <string> bridgingOffsets = new List <string>(); List <object> userStates = new List <object>(); byte[] buffer = new byte[0]; foreach (P2PMessage p2pMessage in sendList) { SLPMessage slpMessage = p2pMessage.IsSLPData ? p2pMessage.InnerMessage as SLPMessage : null; if (slpMessage != null && ((slpMessage.ContentType == "application/x-msnmsgr-transreqbody" || slpMessage.ContentType == "application/x-msnmsgr-transrespbody" || slpMessage.ContentType == "application/x-msnmsgr-transdestaddrupdate"))) { SendOnePacket(session, remote, remoteGuid, p2pMessage); } else { bridgingOffsets.Add(buffer.Length.ToString()); buffer = NetworkMessage.AppendArray(buffer, p2pMessage.GetBytes(true)); int transId = nsmp.IncreaseTransactionID(); userStates.Add(transId); lock (p2pAckMessages) p2pAckMessages[transId] = new P2PMessageSessionEventArgs(p2pMessage, session); //mmMessage.ContentHeaders[MIMEContentHeaders.Pipe] = PackageNo.ToString(); } } if (buffer.Length > 0) { mmMessage.ContentHeaders[MIMEContentHeaders.BridgingOffsets] = String.Join(",", bridgingOffsets.ToArray()); mmMessage.InnerBody = buffer; int transId2 = nsmp.IncreaseTransactionID(); userStates.Add(transId2); NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.TransactionID = transId2; sdgPayload.InnerMessage = mmMessage; nsmp.Processor.Send(sdgPayload.GetBytes(), userStates.ToArray()); } }
internal static RoutingInfo FromMultiMimeMessage(MultiMimeMessage multiMimeMessage, NSMessageHandler nsMessageHandler) { IMAddressInfoType senderAccountAddressType; string senderAccount = string.Empty; IMAddressInfoType senderGatewayAccountAddressType; string senderGatewayAccount = string.Empty; IMAddressInfoType receiverAccountAddressType; string receiverAccount = string.Empty; IMAddressInfoType receiverGatewayAccountAddressType; string receiverGatewayAccount = string.Empty; if ((false == Contact.ParseFullAccount(multiMimeMessage.From.ToString(), out senderAccountAddressType, out senderAccount, out senderGatewayAccountAddressType, out senderGatewayAccount)) || (false == Contact.ParseFullAccount(multiMimeMessage.To.ToString(), out receiverAccountAddressType, out receiverAccount, out receiverGatewayAccountAddressType, out receiverGatewayAccount))) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Cannot parse sender or receiver from message: " + multiMimeMessage.From.ToString() + "|" + multiMimeMessage.To.ToString()); return(null); } Contact sender = null; Contact senderGateway = null; Contact receiver = null; Contact receiverGateway = null; if (multiMimeMessage.From.HasAttribute("via")) { senderGateway = GetGatewayFromAccountString(multiMimeMessage.From["via"], nsMessageHandler); } if (senderGateway == null && multiMimeMessage.RoutingHeaders.ContainsKey(MIMERoutingHeaders.Via)) //The gateway is sender gateway { senderGateway = GetGatewayFromAccountString(multiMimeMessage.RoutingHeaders[MIMERoutingHeaders.Via], nsMessageHandler); } if (multiMimeMessage.To.HasAttribute("via")) { receiverGateway = GetGatewayFromAccountString(multiMimeMessage.To["via"], nsMessageHandler); } bool fromMyself = (senderAccount == nsMessageHandler.Owner.Account && senderAccountAddressType == IMAddressInfoType.WindowsLive); if (!Contact.IsSpecialGatewayType(senderAccountAddressType)) { if (senderGateway == null) { sender = fromMyself ? nsMessageHandler.Owner : nsMessageHandler.ContactList.GetContactWithCreate(senderAccount, senderAccountAddressType); } else { // For facebook, we might need to use GetContact instead of GetContactWithCreate, // that's the official client's behavior. Actually we will get all status notification from // our facebook contacts, however, WLM only display those guys who are also our windows live // contact. For now, those facebook contact doesn't add us as an WLM contact will also show up // in MSNPSharp, their name is the same with the account - all are numbers. I think it doesn't // harm so far, so keep it like this is reasonable, but might change in the future. sender = senderGateway.ContactList.GetContactWithCreate(senderAccount, senderAccountAddressType); } } else { sender = GetGateway(senderAccount, senderAccountAddressType, nsMessageHandler); } bool sentToMe = (receiverAccount == nsMessageHandler.Owner.Account && receiverAccountAddressType == IMAddressInfoType.WindowsLive); if (!Contact.IsSpecialGatewayType(receiverAccountAddressType)) { if (receiverGateway == null) { receiver = sentToMe ? nsMessageHandler.Owner : nsMessageHandler.ContactList.GetContactWithCreate(receiverAccount, receiverAccountAddressType); } else { receiver = receiverGateway.ContactList.GetContactWithCreate(receiverAccount, receiverAccountAddressType); } } else { receiver = GetGateway(receiverAccount, receiverAccountAddressType, nsMessageHandler); } RoutingInfo routingInfo = new RoutingInfo(sender, senderGateway, receiver, receiverGateway, nsMessageHandler); routingInfo.SenderEndPointID = GetEPID(multiMimeMessage.From); routingInfo.SenderAccount = senderAccount; routingInfo.SenderType = senderAccountAddressType; routingInfo.ReceiverEndPointID = GetEPID(multiMimeMessage.To); routingInfo.ReceiverAccount = receiverAccount; routingInfo.ReceiverType = receiverAccountAddressType; return(routingInfo); }