Example #1
0
        internal bool CheckSLPMessage(P2PBridge bridge, Contact source, Guid sourceGuid, P2PMessage msg, SLPMessage slp)
        {
            string src = source.Account.ToLowerInvariant();
            string target = nsMessageHandler.Owner.Account;

            if (slp.FromEmailAccount.ToLowerInvariant() != src)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                    String.Format("Received message from '{0}', differing from source '{1}'", slp.Source, src), GetType().Name);

                return false;
            }
            else if (slp.ToEmailAccount.ToLowerInvariant() != target)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                    String.Format("Received P2P message intended for '{0}', not us '{1}'", slp.Target, target), GetType().Name);

                if (slp.FromEmailAccount == target)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                        "We received a message from ourselves?", GetType().Name);
                }
                else
                {
                    SendSLPStatus(bridge, msg, source, sourceGuid, 404, "Not Found");
                }

                return false;
            }

            return true;
        }
Example #2
0
        internal bool CheckSLPMessage(P2PBridge bridge, Contact source, Guid sourceGuid, P2PMessage msg, SLPMessage slp)
        {
            string src    = source.Account.ToLowerInvariant();
            string target = nsMessageHandler.Owner.Account;

            if (slp.FromEmailAccount.ToLowerInvariant() != src)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("Received message from '{0}', differing from source '{1}'", slp.Source, src), GetType().Name);

                return(false);
            }
            else if (slp.ToEmailAccount.ToLowerInvariant() != target)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("Received P2P message intended for '{0}', not us '{1}'", slp.Target, target), GetType().Name);

                if (slp.FromEmailAccount == target)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                      "We received a message from ourselves?", GetType().Name);
                }
                else
                {
                    SendSLPStatus(bridge, msg, source, sourceGuid, 404, "Not Found");
                }

                return(false);
            }

            return(true);
        }
Example #3
0
        /// <summary>
        /// Move the specified <see cref="P2PSession"/> to the new <see cref="P2PBridge"/> specified.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="newBridge"></param>
        public virtual void MigrateQueue(P2PSession session, P2PBridge newBridge)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                              String.Format("P2PBridge {0} migrating session {1} queue to new bridge {2}",
                                            this.ToString(), session.SessionId, (newBridge != null) ? newBridge.ToString() : "null"), GetType().Name);

            P2PSendQueue newQueue = new P2PSendQueue();

            lock (sendingQueues)
            {
                if (sendingQueues.ContainsKey(session))
                {
                    if (newBridge != null)
                    {
                        lock (sendingQueues[session])
                        {
                            foreach (P2PSendItem item in sendingQueues[session])
                            {
                                newQueue.Enqueue(item);
                            }
                        }
                    }

                    sendingQueues.Remove(session);
                }
            }

            lock (sendQueues)
            {
                if (sendQueues.ContainsKey(session))
                {
                    if (newBridge != null)
                    {
                        while (sendQueues[session].Count > 0)
                        {
                            newQueue.Enqueue(sendQueues[session].Dequeue());
                        }
                    }

                    sendQueues.Remove(session);
                }
            }

            lock (stoppedSessions)
            {
                if (stoppedSessions.Contains(session))
                {
                    stoppedSessions.Remove(session);
                }
            }

            if (newBridge != null)
            {
                newBridge.AddQueue(session, newQueue);
            }
        }
Example #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bridge"></param>
        /// <param name="p2pMessage"></param>
        /// <returns></returns>
        public bool ProcessP2PData(P2PBridge bridge, P2PMessage p2pMessage)
        {
            ResetTimeoutTimer();

            // Keep track of the remote identifier
            remoteIdentifier = (p2pMessage.Version == P2PVersion.P2PV2) ?
                               p2pMessage.Header.Identifier + p2pMessage.Header.MessageSize :
                               p2pMessage.Header.Identifier;

            if (status == P2PSessionStatus.Closed || status == P2PSessionStatus.Error)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("P2PSession {0} received message whilst in '{1}' state", sessionId, status), GetType().Name);

                return(false);
            }

            if (p2pApplication == null)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("P2PSession {0}: Received message for P2P app, but it's either been disposed or not created", sessionId), GetType().Name);

                return(false);
            }
            else
            {
                // Application data
                if (p2pMessage.Header.MessageSize > 0 && p2pMessage.Header.SessionId > 0)
                {
                    bool   reset   = false;
                    byte[] appData = new byte[0];

                    if (p2pMessage.Header.MessageSize == 4 && BitUtility.ToInt32(p2pMessage.InnerBody, 0, true) == 0)
                    {
                        reset = true;
                    }
                    else
                    {
                        appData = new byte[p2pMessage.InnerBody.Length];
                        Buffer.BlockCopy(p2pMessage.InnerBody, 0, appData, 0, appData.Length);
                    }

                    if (p2pMessage.Version == P2PVersion.P2PV2 &&
                        (TFCombination.First == (p2pMessage.V2Header.TFCombination & TFCombination.First)))
                    {
                        reset = true;
                    }

                    return(p2pApplication.ProcessData(bridge, appData, reset));
                }

                return(false);
            }
        }
Example #5
0
        private void BridgeClosed(object sender, EventArgs args)
        {
            P2PBridge bridge = sender as P2PBridge;

            if (!bridges.Contains(bridge))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Closed bridge not found in list", GetType().Name);
                return;
            }

            bridges.Remove(bridge);
        }
Example #6
0
        internal void SendSLPStatus(P2PBridge bridge, P2PMessage msg, Contact dest, Guid destGuid, int code, string phrase)
        {
            string target = dest.Account.ToLowerInvariant();

            if (msg.Version == P2PVersion.P2PV2)
            {
                target += ";" + destGuid.ToString("B");
            }

            SLPMessage slp = new SLPStatusMessage(target, code, phrase);

            if (msg.IsSLPData)
            {
                SLPMessage msgSLP = msg.InnerMessage as SLPMessage;
                slp.Branch      = msgSLP.Branch;
                slp.CallId      = msgSLP.CallId;
                slp.Source      = msgSLP.Target;
                slp.ContentType = msgSLP.ContentType;
                if (msgSLP.BodyValues.ContainsKey("SessionID"))
                {
                    slp.BodyValues["SessionID"] = msgSLP.BodyValues["SessionID"];
                }
            }
            else
            {
                slp.ContentType = "null";
            }

            P2PMessage response = new P2PMessage(msg.Version);

            response.InnerMessage = slp;

            if (msg.Version == P2PVersion.P2PV1)
            {
                response.V1Header.Flags = P2PFlag.MSNSLPInfo;
            }
            else if (msg.Version == P2PVersion.P2PV2)
            {
                response.V2Header.OperationCode = (byte)OperationCode.None;
                response.V2Header.TFCombination = TFCombination.First;
            }

            bridge.Send(null, dest, destGuid, response);
        }
Example #7
0
        private void Migrate(P2PBridge newBridge)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                              String.Format("P2PSession {0} migrating from bridge {1} to {2}",
                                            sessionId, (p2pBridge != null) ? p2pBridge.ToString() : "null",
                                            (newBridge != null) ? newBridge.ToString() : "null"), GetType().Name);

            if (p2pBridge != null)
            {
                p2pBridge.BridgeOpened -= BridgeOpened;
                p2pBridge.BridgeSynced -= BridgeSynced;
                p2pBridge.BridgeClosed -= BridgeClosed;
                p2pBridge.BridgeSent   -= BridgeSent;

                p2pBridge.MigrateQueue(this, newBridge);
            }

            p2pBridge = newBridge;

            if (p2pBridge != null)
            {
                p2pBridge.BridgeOpened += BridgeOpened;
                p2pBridge.BridgeSynced += BridgeSynced;
                p2pBridge.BridgeClosed += BridgeClosed;
                p2pBridge.BridgeSent   += BridgeSent;

                if (localIdentifier == 0)
                {
                    localBaseIdentifier = p2pBridge.SequenceId;
                    localIdentifier     = localBaseIdentifier;
                }
                else
                {
                    p2pBridge.SequenceId = localIdentifier;
                }

                if ((directNegotiationTimer != null) & (p2pBridge is TCPv1Bridge))
                {
                    DirectNegotiationSuccessful();
                }
            }
        }
Example #8
0
        /// <summary>
        /// Creates a new session initiated remotely. If the application cannot be handled, decline message will be sent.
        /// The application will handle all messages automatically and no user interaction is required if AutoAccept is true.
        /// If AutoAccept is false, <see cref="P2PHandler.InvitationReceived"/> event will be fired.
        /// </summary>
        public P2PSession(SLPRequestMessage slp, P2PMessage msg, NSMessageHandler ns, P2PBridge bridge)
        {
            nsMessageHandler = ns;
            invitation       = slp;
            version          = slp.P2PVersion;

            if (version == P2PVersion.P2PV1)
            {
                localContact = (slp.ToEmailAccount == ns.Owner.Account) ?
                               ns.Owner : ns.ContactList.GetContactWithCreate(slp.ToEmailAccount, IMAddressInfoType.WindowsLive);

                remoteContact = ns.ContactList.GetContactWithCreate(slp.FromEmailAccount, IMAddressInfoType.WindowsLive);
            }
            else
            {
                localContact = (slp.ToEmailAccount == ns.Owner.Account) ?
                               ns.Owner : ns.ContactList.GetContactWithCreate(slp.ToEmailAccount, IMAddressInfoType.WindowsLive);
                localContactEndPointID = slp.ToEndPoint;

                remoteContact           = ns.ContactList.GetContactWithCreate(slp.FromEmailAccount, IMAddressInfoType.WindowsLive);
                remoteContactEndPointID = slp.FromEndPoint;
            }

            if (!uint.TryParse(slp.BodyValues["SessionID"].Value, out sessionId))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  "Can't parse SessionID: " + SessionId, GetType().Name);
            }

            p2pBridge           = bridge;
            localBaseIdentifier = bridge.SequenceId;
            localIdentifier     = localBaseIdentifier;
            status = P2PSessionStatus.WaitingForLocal;

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                              String.Format("{0} created (Initiated remotely)", SessionId), GetType().Name);

            remoteContact.DirectBridgeEstablished += RemoteDirectBridgeEstablished;

            if (msg != null)
            {
                // Set remote baseID
                remoteBaseIdentifier = msg.Header.Identifier;
                remoteIdentifier     = remoteBaseIdentifier;

                if (version == P2PVersion.P2PV2)
                {
                    remoteIdentifier += msg.V2Header.MessageSize;
                }
            }

            // Create application based on invitation
            uint appId   = slp.BodyValues.ContainsKey("AppID") ? uint.Parse(slp.BodyValues["AppID"].Value) : 0;
            Guid eufGuid = slp.BodyValues.ContainsKey("EUF-GUID") ? new Guid(slp.BodyValues["EUF-GUID"].Value) : Guid.Empty;

            p2pApplication = P2PApplication.CreateInstance(eufGuid, appId, this);

            if (p2pApplication != null && p2pApplication.ValidateInvitation(invitation))
            {
                if (p2pApplication.AutoAccept)
                {
                    Accept();
                }
                else
                {
                    ns.P2PHandler.OnInvitationReceived(new P2PSessionEventArgs(this));
                }
            }
            else
            {
                Decline();
            }
        }
Example #9
0
        public bool ProcessP2PMessage(P2PBridge bridge, Contact source, Guid sourceGuid, P2PMessage p2pMessage)
        {
            // 1) SLP BUFFERING: Combine splitted SLP messages
            if (slpMessagePool.BufferMessage(ref p2pMessage))
            {
                // * Buffering: Not completed yet, we must wait next packets -OR-
                // * Invalid packet received: Don't kill me, just ignore it...
                return(true);
            }

            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                              String.Format("Received P2PMessage from {0}\r\n{1}", bridge.ToString(), p2pMessage.ToDebugString()), GetType().Name);

            // 2) CHECK SLP: Check destination, source, endpoints
            SLPMessage slp = p2pMessage.IsSLPData ? p2pMessage.InnerMessage as SLPMessage : null;

            if (slp != null)
            {
                if (!slpHandler.CheckSLPMessage(bridge, source, sourceGuid, p2pMessage, slp))
                {
                    return(true); // HANDLED, This SLP is not for us.
                }
            }

            // 3) FIRST SLP MESSAGE: Create applications/sessions based on invitation
            if (slp != null && slp is SLPRequestMessage &&
                (slp as SLPRequestMessage).Method == "INVITE" &&
                slp.ContentType == "application/x-msnmsgr-sessionreqbody")
            {
                uint       appId   = slp.BodyValues.ContainsKey("AppID") ? uint.Parse(slp.BodyValues["AppID"].Value) : 0;
                Guid       eufGuid = slp.BodyValues.ContainsKey("EUF-GUID") ? new Guid(slp.BodyValues["EUF-GUID"].Value) : Guid.Empty;
                P2PVersion ver     = slp.P2PVersion;

                if (P2PApplication.IsRegistered(eufGuid, appId))
                {
                    P2PSession newSession = FindSessionByCallId(slp.CallId, ver);

                    if (newSession == null)
                    {
                        newSession         = new P2PSession(slp as SLPRequestMessage, p2pMessage, nsMessageHandler, bridge);
                        newSession.Closed += P2PSessionClosed;

                        if (newSession.Version == P2PVersion.P2PV2)
                        {
                            p2pV2Sessions.Add(newSession);
                        }
                        else
                        {
                            p2pV1Sessions.Add(newSession);
                        }
                    }
                    else
                    {
                        // P2PSession exists, bridge changed...
                        if (newSession.Bridge != bridge)
                        {
                            // BRIDGETODO
                        }
                    }

                    return(true);
                }

                // Not registered application. Decline it without create a new session...
                slpHandler.SendSLPStatus(bridge, p2pMessage, source, sourceGuid, 603, "Decline");
                return(true);
            }

            // 4) FIND SESSION: Search session by SessionId/ExpectedIdentifier
            P2PSession session = FindSession(p2pMessage, slp);

            if (session != null)
            {
                // ResetTimeoutTimer();

                // Keep track of theremoteIdentifier

                // Keep track of the remote identifier
                session.remoteIdentifier = (p2pMessage.Version == P2PVersion.P2PV2) ?
                                           p2pMessage.Header.Identifier + p2pMessage.Header.MessageSize :
                                           p2pMessage.Header.Identifier;

                // Session SLP
                if (slp != null && slpHandler.HandleP2PSessionSignal(bridge, p2pMessage, slp, session))
                {
                    return(true);
                }

                // Session Data
                if (slp == null && session.ProcessP2PData(bridge, p2pMessage))
                {
                    return(true);
                }
            }

            return(false);
        }
Example #10
0
        public override bool ProcessData(P2PBridge bridge, byte[] data, bool reset)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                "DATA RECEIVED: " + P2PMessage.DumpBytes(data, 128, true), GetType().Name);

            return true;
        }
Example #11
0
        public override bool ProcessData(P2PBridge bridge, byte[] data, bool reset)
        {
            if (sending)
            {
                // We are sender but remote client want to kill me :)
                return false;
            }

            if (reset)
            {
                // Data prep or TFCombination.First
                objStream.SetLength(0);
            }

            if (data.Length > 0)
            {
                objStream.Write(data, 0, data.Length);

                Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                    String.Format("Received {0} / {1}", objStream.Length, msnObject.Size), GetType().Name);

                if (objStream.Length == msnObject.Size)
                {
                    // Finished transfer
                    byte[] allData = new byte[msnObject.Size];

                    objStream.Seek(0, SeekOrigin.Begin);
                    objStream.Read(allData, 0, allData.Length);

                    string dataSha = Convert.ToBase64String(new SHA1Managed().ComputeHash(allData));

                    if (dataSha != msnObject.Sha)
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                            "Object hash doesn't match data hash, data invalid", GetType().Name);

                        return false;
                    }

                    MemoryStream ms = new MemoryStream(allData);
                    ms.Position = 0;

                    // Data CHECKSUM is ok, update MsnObject
                    if (msnObject.ObjectType == MSNObjectType.UserDisplay)
                    {
                        DisplayImage newDisplayImage = new DisplayImage(Remote.Account.ToLowerInvariant(), ms);
                        Remote.SetDisplayImageAndFireDisplayImageChangedEvent(newDisplayImage);

                        msnObject = newDisplayImage;
                    }
                    else if (msnObject.ObjectType == MSNObjectType.Scene)
                    {
                        SceneImage newSceneImage = new SceneImage(Remote.Account.ToLowerInvariant(), ms);
                        Remote.SetSceneImageAndFireSceneImageChangedEvent(newSceneImage);

                        msnObject = newSceneImage;
                    }
                    else if (msnObject.ObjectType == MSNObjectType.Emoticon)
                    {
                        ((Emoticon)msnObject).Image = Image.FromStream(objStream);
                    }
                    else if (msnObject.ObjectType == MSNObjectType.Wink)
                    {
                        Stream s = ((Wink)msnObject).OpenStream();
                        s.Write(allData, 0, allData.Length);
                    }

                    objStream.Close();
                    OnTransferFinished(EventArgs.Empty);

                    if (P2PSession != null)
                        P2PSession.Close(); // Send first BYE
                }
            }
            return true;
        }
Example #12
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="bridge"></param>
 /// <param name="data"></param>
 /// <param name="reset"></param>
 /// <returns></returns>
 public abstract bool ProcessData(P2PBridge bridge, byte[] data, bool reset);
Example #13
0
        internal bool HandleP2PSessionSignal(P2PBridge bridge, P2PMessage p2pMessage, SLPMessage slp, P2PSession session)
        {
            if (slp is SLPRequestMessage)
            {
                SLPRequestMessage slpRequest = slp as SLPRequestMessage;

                if (slpRequest.ContentType == "application/x-msnmsgr-sessionclosebody" &&
                    slpRequest.Method == "BYE")
                {
                    if (p2pMessage.Version == P2PVersion.P2PV1)
                    {
                        P2PMessage byeAck = p2pMessage.CreateAcknowledgement();
                        byeAck.V1Header.Flags = P2PFlag.CloseSession;
                        session.Send(byeAck);
                    }
                    else if (p2pMessage.Version == P2PVersion.P2PV2)
                    {
                        SLPRequestMessage slpMessage = new SLPRequestMessage(session.RemoteContactEPIDString, "BYE");
                        slpMessage.Target = session.RemoteContactEPIDString;
                        slpMessage.Source = session.LocalContactEPIDString;
                        slpMessage.Branch = session.Invitation.Branch;
                        slpMessage.CallId = session.Invitation.CallId;
                        slpMessage.ContentType = "application/x-msnmsgr-sessionclosebody";
                        slpMessage.BodyValues["SessionID"] = session.SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);

                        session.Send(session.WrapSLPMessage(slpMessage));
                    }

                    session.OnClosed(new ContactEventArgs(session.Remote));

                    return true;
                }
                else
                {
                    if (slpRequest.ContentType == "application/x-msnmsgr-transreqbody" ||
                        slpRequest.ContentType == "application/x-msnmsgr-transrespbody" ||
                        slpRequest.ContentType == "application/x-msnmsgr-transdestaddrupdate")
                    {
                        P2PSession.ProcessDirectInvite(slpRequest, nsMessageHandler, session); // Direct connection invite
                        return true;
                    }
                }
            }
            else if (slp is SLPStatusMessage)
            {
                SLPStatusMessage slpStatus = slp as SLPStatusMessage;

                if (slpStatus.Code == 200) // OK
                {
                    if (slpStatus.ContentType == "application/x-msnmsgr-transrespbody")
                    {
                        P2PSession.ProcessDirectInvite(slpStatus, nsMessageHandler, session);

                        return true;
                    }
                    else
                    {
                        if (session.Application != null)
                        {
                            session.OnActive(EventArgs.Empty);
                            session.Application.Start();

                            return true;
                        }
                    }
                }
                else if (slpStatus.Code == 603) // Decline
                {
                    session.OnClosed(new ContactEventArgs(session.Remote));

                    return true;
                }
                else if (slpStatus.Code == 500) // Internal Error
                {
                    return true;
                }
            }

            Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                 String.Format("Unhandled SLP Message in session:---->>\r\n{0}", p2pMessage.ToString()), GetType().Name);

            session.OnError(EventArgs.Empty);
            return true;
        }
Example #14
0
        internal void SendSLPStatus(P2PBridge bridge, P2PMessage msg, Contact dest, Guid destGuid, int code, string phrase)
        {
            string target = dest.Account.ToLowerInvariant();

            if (msg.Version == P2PVersion.P2PV2)
            {
                target += ";" + destGuid.ToString("B");
            }

            SLPMessage slp = new SLPStatusMessage(target, code, phrase);

            if (msg.IsSLPData)
            {
                SLPMessage msgSLP = msg.InnerMessage as SLPMessage;
                slp.Branch = msgSLP.Branch;
                slp.CallId = msgSLP.CallId;
                slp.Source = msgSLP.Target;
                slp.ContentType = msgSLP.ContentType;
                if (msgSLP.BodyValues.ContainsKey("SessionID"))
                {
                    slp.BodyValues["SessionID"] = msgSLP.BodyValues["SessionID"];
                }

            }
            else
                slp.ContentType = "null";

            P2PMessage response = new P2PMessage(msg.Version);
            response.InnerMessage = slp;

            if (msg.Version == P2PVersion.P2PV1)
            {
                response.V1Header.Flags = P2PFlag.MSNSLPInfo;
            }
            else if (msg.Version == P2PVersion.P2PV2)
            {
                response.V2Header.OperationCode = (byte)OperationCode.None;
                response.V2Header.TFCombination = TFCombination.First;
            }

            bridge.Send(null, dest, destGuid, response);
        }
Example #15
0
        public bool ProcessP2PMessage(P2PBridge bridge, Contact source, Guid sourceGuid, P2PMessage p2pMessage)
        {
            // 1) SLP BUFFERING: Combine splitted SLP messages
            if (slpMessagePool.BufferMessage(ref p2pMessage))
            {
                // * Buffering: Not completed yet, we must wait next packets -OR-
                // * Invalid packet received: Don't kill me, just ignore it...
                return true;
            }

            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                String.Format("Received P2PMessage from {0}\r\n{1}", bridge.ToString(), p2pMessage.ToDebugString()), GetType().Name);

            // 2) CHECK SLP: Check destination, source, endpoints
            SLPMessage slp = p2pMessage.IsSLPData ? p2pMessage.InnerMessage as SLPMessage : null;
            if (slp != null)
            {
                if (!slpHandler.CheckSLPMessage(bridge, source, sourceGuid, p2pMessage, slp))
                    return true; // HANDLED, This SLP is not for us.
            }

            // 3) FIRST SLP MESSAGE: Create applications/sessions based on invitation
            if (slp != null && slp is SLPRequestMessage &&
                (slp as SLPRequestMessage).Method == "INVITE" &&
                slp.ContentType == "application/x-msnmsgr-sessionreqbody")
            {
                uint appId = slp.BodyValues.ContainsKey("AppID") ? uint.Parse(slp.BodyValues["AppID"].Value) : 0;
                Guid eufGuid = slp.BodyValues.ContainsKey("EUF-GUID") ? new Guid(slp.BodyValues["EUF-GUID"].Value) : Guid.Empty;
                P2PVersion ver = slp.P2PVersion;

                if (P2PApplication.IsRegistered(eufGuid, appId))
                {
                    P2PSession newSession = FindSessionByCallId(slp.CallId, ver);

                    if (newSession == null)
                    {
                        newSession = new P2PSession(slp as SLPRequestMessage, p2pMessage, nsMessageHandler, bridge);
                        newSession.Closed += P2PSessionClosed;

                        if (newSession.Version == P2PVersion.P2PV2)
                            p2pV2Sessions.Add(newSession);
                        else
                            p2pV1Sessions.Add(newSession);
                    }
                    else
                    {
                        // P2PSession exists, bridge changed...
                        if (newSession.Bridge != bridge)
                        {
                            // BRIDGETODO
                        }
                    }

                    return true;
                }

                // Not registered application. Decline it without create a new session...
                slpHandler.SendSLPStatus(bridge, p2pMessage, source, sourceGuid, 603, "Decline");
                return true;
            }

            // 4) FIND SESSION: Search session by SessionId/ExpectedIdentifier
            P2PSession session = FindSession(p2pMessage, slp);
            if (session != null)
            {
                // ResetTimeoutTimer();

                // Keep track of theremoteIdentifier

                // Keep track of the remote identifier
                session.remoteIdentifier = (p2pMessage.Version == P2PVersion.P2PV2) ?
                    p2pMessage.Header.Identifier + p2pMessage.Header.MessageSize :
                    p2pMessage.Header.Identifier;

                // Session SLP
                if (slp != null && slpHandler.HandleP2PSessionSignal(bridge, p2pMessage, slp, session))
                    return true;

                // Session Data
                if (slp == null && session.ProcessP2PData(bridge, p2pMessage))
                    return true;
            }

            return false;
        }
Example #16
0
        internal bool HandleP2PSessionSignal(P2PBridge bridge, P2PMessage p2pMessage, SLPMessage slp, P2PSession session)
        {
            if (slp is SLPRequestMessage)
            {
                SLPRequestMessage slpRequest = slp as SLPRequestMessage;

                if (slpRequest.ContentType == "application/x-msnmsgr-sessionclosebody" &&
                    slpRequest.Method == "BYE")
                {
                    if (p2pMessage.Version == P2PVersion.P2PV1)
                    {
                        P2PMessage byeAck = p2pMessage.CreateAcknowledgement();
                        byeAck.V1Header.Flags = P2PFlag.CloseSession;
                        session.Send(byeAck);
                    }
                    else if (p2pMessage.Version == P2PVersion.P2PV2)
                    {
                        SLPRequestMessage slpMessage = new SLPRequestMessage(session.RemoteContactEPIDString, "BYE");
                        slpMessage.Target                  = session.RemoteContactEPIDString;
                        slpMessage.Source                  = session.LocalContactEPIDString;
                        slpMessage.Branch                  = session.Invitation.Branch;
                        slpMessage.CallId                  = session.Invitation.CallId;
                        slpMessage.ContentType             = "application/x-msnmsgr-sessionclosebody";
                        slpMessage.BodyValues["SessionID"] = session.SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);

                        session.Send(session.WrapSLPMessage(slpMessage));
                    }

                    session.OnClosed(new ContactEventArgs(session.Remote));

                    return(true);
                }
                else
                {
                    if (slpRequest.ContentType == "application/x-msnmsgr-transreqbody" ||
                        slpRequest.ContentType == "application/x-msnmsgr-transrespbody" ||
                        slpRequest.ContentType == "application/x-msnmsgr-transdestaddrupdate")
                    {
                        P2PSession.ProcessDirectInvite(slpRequest, nsMessageHandler, session); // Direct connection invite
                        return(true);
                    }
                }
            }
            else if (slp is SLPStatusMessage)
            {
                SLPStatusMessage slpStatus = slp as SLPStatusMessage;

                if (slpStatus.Code == 200) // OK
                {
                    if (slpStatus.ContentType == "application/x-msnmsgr-transrespbody")
                    {
                        P2PSession.ProcessDirectInvite(slpStatus, nsMessageHandler, session);

                        return(true);
                    }
                    else
                    {
                        if (session.Application != null)
                        {
                            session.OnActive(EventArgs.Empty);
                            session.Application.Start();

                            return(true);
                        }
                    }
                }
                else if (slpStatus.Code == 603) // Decline
                {
                    session.OnClosed(new ContactEventArgs(session.Remote));

                    return(true);
                }
                else if (slpStatus.Code == 500) // Internal Error
                {
                    return(true);
                }
            }

            Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                              String.Format("Unhandled SLP Message in session:---->>\r\n{0}", p2pMessage.ToString()), GetType().Name);

            session.OnError(EventArgs.Empty);
            return(true);
        }
Example #17
0
        /// <summary>
        /// Move the specified <see cref="P2PSession"/> to the new <see cref="P2PBridge"/> specified.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="newBridge"></param>
        public virtual void MigrateQueue(P2PSession session, P2PBridge newBridge)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
               String.Format("P2PBridge {0} migrating session {1} queue to new bridge {2}",
               this.ToString(), session.SessionId, (newBridge != null) ? newBridge.ToString() : "null"), GetType().Name);

            P2PSendQueue newQueue = new P2PSendQueue();
            lock (sendingQueues)
            {
                if (sendingQueues.ContainsKey(session))
                {
                    if (newBridge != null)
                    {
                        lock (sendingQueues[session])
                        {
                            foreach (P2PSendItem item in sendingQueues[session])
                                newQueue.Enqueue(item);
                        }
                    }

                    sendingQueues.Remove(session);
                }
            }

            lock (sendQueues)
            {
                if (sendQueues.ContainsKey(session))
                {
                    if (newBridge != null)
                    {
                        while (sendQueues[session].Count > 0)
                            newQueue.Enqueue(sendQueues[session].Dequeue());
                    }

                    sendQueues.Remove(session);
                }
            }

            lock (stoppedSessions)
            {
                if (stoppedSessions.Contains(session))
                {
                    stoppedSessions.Remove(session);
                }
            }

            if (newBridge != null)
                newBridge.AddQueue(session, newQueue);
        }
Example #18
0
        public override bool ProcessData(P2PBridge bridge, byte[] data, bool reset)
        {
            if (_sending)
            {
                // We are sender but remote client want to kill me :)
                return false;
            }

            if (reset)
            {
                _dataStream.SetLength(0);
            }

            if (data.Length > 0)
                _dataStream.Write(data, 0, data.Length);

            OnProgressed(EventArgs.Empty);

            if (_dataStream.Length == (long)_context.FileSize)
            {
                // Finished transfer
                OnTransferFinished(EventArgs.Empty);
                P2PSession.Close();
            }

            return true;
        }
Example #19
0
        private void Migrate(P2PBridge newBridge)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                      String.Format("P2PSession {0} migrating from bridge {1} to {2}",
                      sessionId, (p2pBridge != null) ? p2pBridge.ToString() : "null",
                      (newBridge != null) ? newBridge.ToString() : "null"), GetType().Name);

            if (p2pBridge != null)
            {
                p2pBridge.BridgeOpened -= BridgeOpened;
                p2pBridge.BridgeSynced -= BridgeSynced;
                p2pBridge.BridgeClosed -= BridgeClosed;
                p2pBridge.BridgeSent -= BridgeSent;

                p2pBridge.MigrateQueue(this, newBridge);
            }

            p2pBridge = newBridge;

            if (p2pBridge != null)
            {
                p2pBridge.BridgeOpened += BridgeOpened;
                p2pBridge.BridgeSynced += BridgeSynced;
                p2pBridge.BridgeClosed += BridgeClosed;
                p2pBridge.BridgeSent += BridgeSent;

                if (localIdentifier == 0)
                {
                    localBaseIdentifier = p2pBridge.SequenceId;
                    localIdentifier = localBaseIdentifier;
                }
                else
                {
                    p2pBridge.SequenceId = localIdentifier;
                }

                if ((directNegotiationTimer != null) & (p2pBridge is TCPv1Bridge))
                    DirectNegotiationSuccessful();
            }
        }
Example #20
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bridge"></param>
        /// <param name="p2pMessage"></param>
        /// <returns></returns>
        public bool ProcessP2PData(P2PBridge bridge, P2PMessage p2pMessage)
        {
            ResetTimeoutTimer();

            // Keep track of the remote identifier
            remoteIdentifier = (p2pMessage.Version == P2PVersion.P2PV2) ?
                p2pMessage.Header.Identifier + p2pMessage.Header.MessageSize :
                p2pMessage.Header.Identifier;

            if (status == P2PSessionStatus.Closed || status == P2PSessionStatus.Error)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                       String.Format("P2PSession {0} received message whilst in '{1}' state", sessionId, status), GetType().Name);

                return false;
            }

            if (p2pApplication == null)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                      String.Format("P2PSession {0}: Received message for P2P app, but it's either been disposed or not created", sessionId), GetType().Name);

                return false;
            }
            else
            {
                // Application data
                if (p2pMessage.Header.MessageSize > 0 && p2pMessage.Header.SessionId > 0)
                {
                    bool reset = false;
                    byte[] appData = new byte[0];

                    if (p2pMessage.Header.MessageSize == 4 && BitUtility.ToInt32(p2pMessage.InnerBody, 0, true) == 0)
                    {
                        reset = true;
                    }
                    else
                    {
                        appData = new byte[p2pMessage.InnerBody.Length];
                        Buffer.BlockCopy(p2pMessage.InnerBody, 0, appData, 0, appData.Length);
                    }

                    if (p2pMessage.Version == P2PVersion.P2PV2 &&
                        (TFCombination.First == (p2pMessage.V2Header.TFCombination & TFCombination.First)))
                    {
                        reset = true;
                    }

                    return p2pApplication.ProcessData(bridge, appData, reset);
                }

                return false;
            }
        }
Example #21
0
        /// <summary>
        /// Creates a new session initiated remotely. If the application cannot be handled, decline message will be sent.
        /// The application will handle all messages automatically and no user interaction is required if AutoAccept is true.
        /// If AutoAccept is false, <see cref="P2PHandler.InvitationReceived"/> event will be fired.
        /// </summary>
        public P2PSession(SLPRequestMessage slp, P2PMessage msg, NSMessageHandler ns, P2PBridge bridge)
        {
            nsMessageHandler = ns;
            invitation = slp;
            version = slp.P2PVersion;

            if (version == P2PVersion.P2PV1)
            {
                localContact = (slp.ToEmailAccount == ns.Owner.Account) ?
                    ns.Owner : ns.ContactList.GetContactWithCreate(slp.ToEmailAccount, IMAddressInfoType.WindowsLive);

                remoteContact = ns.ContactList.GetContactWithCreate(slp.FromEmailAccount, IMAddressInfoType.WindowsLive);
            }
            else
            {
                localContact = (slp.ToEmailAccount == ns.Owner.Account) ?
                    ns.Owner : ns.ContactList.GetContactWithCreate(slp.ToEmailAccount, IMAddressInfoType.WindowsLive);
                localContactEndPointID = slp.ToEndPoint;

                remoteContact = ns.ContactList.GetContactWithCreate(slp.FromEmailAccount, IMAddressInfoType.WindowsLive);
                remoteContactEndPointID = slp.FromEndPoint;
            }

            if (!uint.TryParse(slp.BodyValues["SessionID"].Value, out sessionId))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                    "Can't parse SessionID: " + SessionId, GetType().Name);
            }

            p2pBridge = bridge;
            localBaseIdentifier = bridge.SequenceId;
            localIdentifier = localBaseIdentifier;
            status = P2PSessionStatus.WaitingForLocal;

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
              String.Format("{0} created (Initiated remotely)", SessionId), GetType().Name);

            remoteContact.DirectBridgeEstablished += RemoteDirectBridgeEstablished;

            if (msg != null)
            {
                // Set remote baseID
                remoteBaseIdentifier = msg.Header.Identifier;
                remoteIdentifier = remoteBaseIdentifier;

                if (version == P2PVersion.P2PV2)
                    remoteIdentifier += msg.V2Header.MessageSize;
            }

            // Create application based on invitation
            uint appId = slp.BodyValues.ContainsKey("AppID") ? uint.Parse(slp.BodyValues["AppID"].Value) : 0;
            Guid eufGuid = slp.BodyValues.ContainsKey("EUF-GUID") ? new Guid(slp.BodyValues["EUF-GUID"].Value) : Guid.Empty;
            p2pApplication = P2PApplication.CreateInstance(eufGuid, appId, this);

            if (p2pApplication != null && p2pApplication.ValidateInvitation(invitation))
            {
                if (p2pApplication.AutoAccept)
                {
                    Accept();
                }
                else
                {
                    ns.P2PHandler.OnInvitationReceived(new P2PSessionEventArgs(this));
                }
            }
            else
            {
                Decline();
            }
        }