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);
        }
Beispiel #2
0
        internal bool HandleACK(P2PMessage p2pMessage)
        {
            bool isAckOrNak = false;

            if (p2pMessage.Header.IsAcknowledgement || p2pMessage.Header.IsNegativeAck)
            {
                P2PAckMessageEventArgs e = null;
                uint ackNakId = 0;
                isAckOrNak = true;

                if (p2pMessage.Version == P2PVersion.P2PV1)
                {
                    lock (ackHandlersV1)
                    {
                        if (ackHandlersV1.ContainsKey(p2pMessage.Header.AckIdentifier))
                        {
                            ackNakId = p2pMessage.Header.AckIdentifier;
                            e = ackHandlersV1[ackNakId];
                            ackHandlersV1.Remove(ackNakId);
                        }
                    }
                }
                else if (p2pMessage.Version == P2PVersion.P2PV2)
                {
                    lock (ackHandlersV2)
                    {
                        if (ackHandlersV2.ContainsKey(p2pMessage.Header.AckIdentifier))
                        {
                            ackNakId = p2pMessage.Header.AckIdentifier;
                            e = ackHandlersV2[ackNakId];
                            ackHandlersV2.Remove(ackNakId);
                        }
                        else if (ackHandlersV2.ContainsKey(p2pMessage.V2Header.NakIdentifier))
                        {
                            ackNakId = p2pMessage.V2Header.NakIdentifier;
                            e = ackHandlersV2[ackNakId];
                            ackHandlersV2.Remove(ackNakId);
                        }
                    }
                }

                if (ackNakId == 0)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                        String.Format("!!!!!! No AckHandler registered for ack/nak {0}:\r\n{1}", p2pMessage.Header.AckIdentifier, p2pMessage.ToDebugString()), GetType().Name);
                }
                else
                {
                    if (e != null && e.AckHandler != null)
                    {
                        e.AckHandler(p2pMessage);
                    }
                    else
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                            String.Format("!!!!!! No AckHandler pair for ack {0}\r\n{1}", ackNakId, p2pMessage.ToDebugString()), GetType().Name);
                    }
                }
            }

            return isAckOrNak;
        }
Beispiel #3
0
        /// <summary>
        /// Buffers incompleted P2PMessage SLP messages. Ignores data and control messages. 
        /// </summary>
        /// <param name="p2pMessage"></param>
        /// <returns>
        /// true if the P2PMessage is buffering (not completed) or invalid packet received;
        /// false if the p2p message fully buffered or no need to buffer.
        /// </returns>
        public bool BufferMessage(ref P2PMessage p2pMessage)
        {
            // P2PV1 and P2PV2 check
            if (p2pMessage.Header.MessageSize == 0 || // Ack message or Unsplitted
                p2pMessage.Header.SessionId > 0) // Data message
            {
                return false; // No need to buffer
            }

            // P2PV2 pooling
            if (p2pMessage.Version == P2PVersion.P2PV2)
            {
                if ((p2pMessage.V2Header.TFCombination == TFCombination.First && p2pMessage.V2Header.DataRemaining == 0) || // Unsplitted SLP message or data preparation message
                    (p2pMessage.V2Header.TFCombination > TFCombination.First)) // Data message
                {
                    return false; // No need to buffer
                }

                // First splitted SLP message.
                if (p2pMessage.V2Header.TFCombination == TFCombination.First &&
                    p2pMessage.V2Header.DataRemaining > 0)
                {
                    P2PMessage totalMessage = new P2PMessage(p2pMessage); // Copy it
                    ulong totalSize = (ulong)(p2pMessage.V2Header.MessageSize - p2pMessage.V2Header.DataPacketHeaderLength) +
                        p2pMessage.V2Header.DataRemaining;

                    totalMessage.InnerBody = new byte[totalSize]; // Allocate buffer as needed
                    Array.Copy(p2pMessage.InnerBody, 0, totalMessage.InnerBody, (long)0, (long)p2pMessage.InnerBody.Length);

                    lock (incompletedP2PV2Messages)
                        incompletedP2PV2Messages[p2pMessage.V2Header.Identifier + p2pMessage.V2Header.MessageSize] = totalMessage;

                    return true; // Buffering
                }

                // Other splitted SLP messages
                if (p2pMessage.V2Header.TFCombination == TFCombination.None)
                {
                    lock (incompletedP2PV2Messages)
                    {
                        if (incompletedP2PV2Messages.ContainsKey(p2pMessage.V2Header.Identifier))
                        {
                            if (incompletedP2PV2Messages[p2pMessage.V2Header.Identifier].V2Header.PackageNumber == p2pMessage.V2Header.PackageNumber)
                            {
                                P2PMessage totalMessage = incompletedP2PV2Messages[p2pMessage.V2Header.Identifier];
                                ulong dataSize = Math.Min(((ulong)(p2pMessage.V2Header.MessageSize - p2pMessage.V2Header.DataPacketHeaderLength)), totalMessage.V2Header.DataRemaining);
                                ulong offSet = ((ulong)totalMessage.InnerBody.LongLength) - totalMessage.V2Header.DataRemaining;

                                // Check range and buffer overflow...
                                if (((p2pMessage.V2Header.DataRemaining + (ulong)dataSize) == totalMessage.V2Header.DataRemaining) &&
                                    (ulong)(dataSize + offSet + p2pMessage.V2Header.DataRemaining) == (ulong)totalMessage.InnerBody.LongLength)
                                {
                                    Array.Copy(p2pMessage.InnerBody, 0, totalMessage.InnerBody, (long)offSet, (long)dataSize);
                                    uint originalIdentifier = p2pMessage.V2Header.Identifier;
                                    uint newIdentifier = p2pMessage.V2Header.Identifier + p2pMessage.V2Header.MessageSize;

                                    totalMessage.V2Header.DataRemaining = p2pMessage.V2Header.DataRemaining;
                                    totalMessage.V2Header.Identifier = newIdentifier;

                                    if (originalIdentifier != newIdentifier)
                                    {
                                        incompletedP2PV2Messages.Remove(originalIdentifier);
                                    }

                                    // Don't debug p2p inner packet (SLP) here.
                                    Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                                        " Buffering splitted SLP message! DataRemaining:" + totalMessage.V2Header.DataRemaining +
                                        " NewIdentifier: " + newIdentifier);

                                    if (p2pMessage.V2Header.DataRemaining > 0)
                                    {
                                        // Don't debug p2p packet here. Because it hasn't completed yet and SLPMessage.Parse() fails...
                                        incompletedP2PV2Messages[newIdentifier] = totalMessage;
                                        return true; // Buffering
                                    }
                                    else // Last part
                                    {
                                        totalMessage.InnerBody = totalMessage.InnerBody; // Refresh... DataRemaining=0 deletes data headers.
                                        totalMessage.V2Header.Identifier = newIdentifier - totalMessage.Header.MessageSize;

                                        Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                                            "A splitted message was combined :\r\n" +
                                            totalMessage.ToDebugString());

                                        p2pMessage = totalMessage;
                                        return false; // We have the whole message
                                    }
                                }
                            }

                            // Invalid packet received!!! Ignore and delete it...
                            incompletedP2PV2Messages.Remove(p2pMessage.V2Header.Identifier);

                            Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                "INVALID P2PV2 PACKET received!!! Ignored and deleted:\r\n" +
                                p2pMessage.ToDebugString());
                        }
                    }
                }
            }
            else // P2PV1 pooling
            {
                if ((p2pMessage.V1Header.MessageSize == p2pMessage.V1Header.TotalSize) || // Whole data
                    ((p2pMessage.V1Header.Flags & P2PFlag.Data) == P2PFlag.Data)) // Data message
                {
                    return false; // No need to buffer
                }

                lock (incompletedP2PV1Messages)
                {
                    if (false == incompletedP2PV1Messages.ContainsKey(p2pMessage.Header.Identifier))
                    {
                        byte[] totalPayload = new byte[p2pMessage.V1Header.TotalSize];
                        Array.Copy(p2pMessage.InnerBody, 0, totalPayload, (long)p2pMessage.V1Header.Offset, (long)p2pMessage.V1Header.MessageSize);
                        P2PMessage copyMessage = new P2PMessage(p2pMessage);

                        copyMessage.InnerBody = totalPayload;
                        copyMessage.V1Header.Offset = p2pMessage.V1Header.Offset + p2pMessage.V1Header.MessageSize;

                        incompletedP2PV1Messages[p2pMessage.Header.Identifier] = copyMessage;
                        return true; // Buffering
                    }

                    P2PMessage totalMessage = incompletedP2PV1Messages[p2pMessage.Header.Identifier];
                    if (p2pMessage.V1Header.TotalSize == totalMessage.V1Header.TotalSize &&
                        (p2pMessage.V1Header.Offset + p2pMessage.V1Header.MessageSize) <= totalMessage.Header.TotalSize)
                    {
                        Array.Copy(p2pMessage.InnerBody, 0, totalMessage.InnerBody, (long)p2pMessage.V1Header.Offset, (long)p2pMessage.V1Header.MessageSize);
                        totalMessage.V1Header.Offset = p2pMessage.V1Header.Offset + p2pMessage.V1Header.MessageSize;

                        // Last packet
                        if (totalMessage.V1Header.Offset == p2pMessage.V1Header.TotalSize)
                        {
                            totalMessage.V1Header.Offset = 0;
                            incompletedP2PV1Messages.Remove(p2pMessage.Header.Identifier);

                            p2pMessage = totalMessage;
                            return false; // We have the whole message
                        }

                        return true; // Buffering
                    }

                    // Invalid packet received!!! Ignore and delete it...
                    incompletedP2PV1Messages.Remove(p2pMessage.Header.Identifier);

                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                        "INVALID P2PV1 PACKET received!!! Ignored and deleted:\r\n" +
                        p2pMessage.ToDebugString());
                }
            }

            return true; // Invalid packet, don't kill me.
        }
Beispiel #4
0
        public void ProcessP2PMessage(Contact source, Guid sourceGuid, P2PMessage p2pMessage)
        {
            // HANDLE RAK: RAKs are session independent and mustn't be quoted on bridges.
            bool requireAck = HandleRAK(source, sourceGuid, p2pMessage);

            // HANDLE ACK: ACK/NAK to our RAK message
            if (HandleACK(p2pMessage))
            {
                return;
            }

            // PASS TO P2PHandler
            if (nsMessageHandler.P2PHandler.ProcessP2PMessage(this, source, sourceGuid, p2pMessage))
            {
                return;
            }

            if (!requireAck)
            {
                // UNHANDLED P2P MESSAGE
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                    String.Format("*******Unhandled P2P message ****** \r\n{0}", p2pMessage.ToDebugString()), GetType().Name);

                // Keep RemoteID Synchronized, I think we must track remoteIdentifier here...
                // Send NAK??????

            }
        }
        /// <summary>
        /// Buffers incompleted P2PMessage SLP messages. Ignores data and control messages.
        /// </summary>
        /// <param name="p2pMessage"></param>
        /// <returns>
        /// true if the P2PMessage is buffering (not completed) or invalid packet received;
        /// false if the p2p message fully buffered or no need to buffer.
        /// </returns>
        public bool BufferMessage(ref P2PMessage p2pMessage)
        {
            // P2PV1 and P2PV2 check
            if (p2pMessage.Header.MessageSize == 0 || // Ack message or Unsplitted
                p2pMessage.Header.SessionId > 0)      // Data message
            {
                return(false);                        // No need to buffer
            }

            // P2PV2 pooling
            if (p2pMessage.Version == P2PVersion.P2PV2)
            {
                if ((p2pMessage.V2Header.TFCombination == TFCombination.First && p2pMessage.V2Header.DataRemaining == 0) || // Unsplitted SLP message or data preparation message
                    (p2pMessage.V2Header.TFCombination > TFCombination.First))                                              // Data message
                {
                    return(false);                                                                                          // No need to buffer
                }

                // First splitted SLP message.
                if (p2pMessage.V2Header.TFCombination == TFCombination.First &&
                    p2pMessage.V2Header.DataRemaining > 0)
                {
                    P2PMessage totalMessage = new P2PMessage(p2pMessage); // Copy it
                    ulong      totalSize    = (ulong)(p2pMessage.V2Header.MessageSize - p2pMessage.V2Header.DataPacketHeaderLength) +
                                              p2pMessage.V2Header.DataRemaining;

                    totalMessage.InnerBody = new byte[totalSize]; // Allocate buffer as needed
                    Array.Copy(p2pMessage.InnerBody, 0, totalMessage.InnerBody, (long)0, (long)p2pMessage.InnerBody.Length);

                    lock (incompletedP2PV2Messages)
                        incompletedP2PV2Messages[p2pMessage.V2Header.Identifier + p2pMessage.V2Header.MessageSize] = totalMessage;

                    return(true); // Buffering
                }

                // Other splitted SLP messages
                if (p2pMessage.V2Header.TFCombination == TFCombination.None)
                {
                    lock (incompletedP2PV2Messages)
                    {
                        if (incompletedP2PV2Messages.ContainsKey(p2pMessage.V2Header.Identifier))
                        {
                            if (incompletedP2PV2Messages[p2pMessage.V2Header.Identifier].V2Header.PackageNumber == p2pMessage.V2Header.PackageNumber)
                            {
                                P2PMessage totalMessage = incompletedP2PV2Messages[p2pMessage.V2Header.Identifier];
                                ulong      dataSize     = Math.Min(((ulong)(p2pMessage.V2Header.MessageSize - p2pMessage.V2Header.DataPacketHeaderLength)), totalMessage.V2Header.DataRemaining);
                                ulong      offSet       = ((ulong)totalMessage.InnerBody.LongLength) - totalMessage.V2Header.DataRemaining;

                                // Check range and buffer overflow...
                                if (((p2pMessage.V2Header.DataRemaining + (ulong)dataSize) == totalMessage.V2Header.DataRemaining) &&
                                    (ulong)(dataSize + offSet + p2pMessage.V2Header.DataRemaining) == (ulong)totalMessage.InnerBody.LongLength)
                                {
                                    Array.Copy(p2pMessage.InnerBody, 0, totalMessage.InnerBody, (long)offSet, (long)dataSize);
                                    uint originalIdentifier = p2pMessage.V2Header.Identifier;
                                    uint newIdentifier      = p2pMessage.V2Header.Identifier + p2pMessage.V2Header.MessageSize;

                                    totalMessage.V2Header.DataRemaining = p2pMessage.V2Header.DataRemaining;
                                    totalMessage.V2Header.Identifier    = newIdentifier;

                                    if (originalIdentifier != newIdentifier)
                                    {
                                        incompletedP2PV2Messages.Remove(originalIdentifier);
                                    }

                                    // Don't debug p2p inner packet (SLP) here.
                                    Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                                                      " Buffering splitted SLP message! DataRemaining:" + totalMessage.V2Header.DataRemaining +
                                                      " NewIdentifier: " + newIdentifier);

                                    if (p2pMessage.V2Header.DataRemaining > 0)
                                    {
                                        // Don't debug p2p packet here. Because it hasn't completed yet and SLPMessage.Parse() fails...
                                        incompletedP2PV2Messages[newIdentifier] = totalMessage;
                                        return(true); // Buffering
                                    }
                                    else // Last part
                                    {
                                        totalMessage.InnerBody           = totalMessage.InnerBody; // Refresh... DataRemaining=0 deletes data headers.
                                        totalMessage.V2Header.Identifier = newIdentifier - totalMessage.Header.MessageSize;

                                        Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                                                          "A splitted message was combined :\r\n" +
                                                          totalMessage.ToDebugString());

                                        p2pMessage = totalMessage;
                                        return(false); // We have the whole message
                                    }
                                }
                            }

                            // Invalid packet received!!! Ignore and delete it...
                            incompletedP2PV2Messages.Remove(p2pMessage.V2Header.Identifier);

                            Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                              "INVALID P2PV2 PACKET received!!! Ignored and deleted:\r\n" +
                                              p2pMessage.ToDebugString());
                        }
                    }
                }
            }
            else // P2PV1 pooling
            {
                if ((p2pMessage.V1Header.MessageSize == p2pMessage.V1Header.TotalSize) || // Whole data
                    ((p2pMessage.V1Header.Flags & P2PFlag.Data) == P2PFlag.Data)) // Data message
                {
                    return(false);                                                // No need to buffer
                }

                lock (incompletedP2PV1Messages)
                {
                    if (false == incompletedP2PV1Messages.ContainsKey(p2pMessage.Header.Identifier))
                    {
                        byte[] totalPayload = new byte[p2pMessage.V1Header.TotalSize];
                        Array.Copy(p2pMessage.InnerBody, 0, totalPayload, (long)p2pMessage.V1Header.Offset, (long)p2pMessage.V1Header.MessageSize);
                        P2PMessage copyMessage = new P2PMessage(p2pMessage);

                        copyMessage.InnerBody       = totalPayload;
                        copyMessage.V1Header.Offset = p2pMessage.V1Header.Offset + p2pMessage.V1Header.MessageSize;

                        incompletedP2PV1Messages[p2pMessage.Header.Identifier] = copyMessage;
                        return(true); // Buffering
                    }

                    P2PMessage totalMessage = incompletedP2PV1Messages[p2pMessage.Header.Identifier];
                    if (p2pMessage.V1Header.TotalSize == totalMessage.V1Header.TotalSize &&
                        (p2pMessage.V1Header.Offset + p2pMessage.V1Header.MessageSize) <= totalMessage.Header.TotalSize)
                    {
                        Array.Copy(p2pMessage.InnerBody, 0, totalMessage.InnerBody, (long)p2pMessage.V1Header.Offset, (long)p2pMessage.V1Header.MessageSize);
                        totalMessage.V1Header.Offset = p2pMessage.V1Header.Offset + p2pMessage.V1Header.MessageSize;

                        // Last packet
                        if (totalMessage.V1Header.Offset == p2pMessage.V1Header.TotalSize)
                        {
                            totalMessage.V1Header.Offset = 0;
                            incompletedP2PV1Messages.Remove(p2pMessage.Header.Identifier);

                            p2pMessage = totalMessage;
                            return(false); // We have the whole message
                        }

                        return(true); // Buffering
                    }

                    // Invalid packet received!!! Ignore and delete it...
                    incompletedP2PV1Messages.Remove(p2pMessage.Header.Identifier);

                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                      "INVALID P2PV1 PACKET received!!! Ignored and deleted:\r\n" +
                                      p2pMessage.ToDebugString());
                }
            }

            return(true); // Invalid packet, don't kill me.
        }
Beispiel #6
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;
        }
Beispiel #7
0
        public void ProcessP2PMessage(Contact source, Guid sourceGuid, P2PMessage p2pMessage)
        {
            // HANDLE RAK: RAKs are session independent and mustn't be quoted on bridges.
            bool requireAck = HandleRAK(source, sourceGuid, p2pMessage);

            // HANDLE ACK: ACK/NAK to our RAK message
            if (HandleACK(p2pMessage))
            {
                return;
            }

            // PASS TO P2PHandler
            if (nsMessageHandler.P2PHandler.ProcessP2PMessage(this, source, sourceGuid, p2pMessage))
            {
                return;
            }

            if (!requireAck)
            {
                // UNHANDLED P2P MESSAGE
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("*******Unhandled P2P message ****** \r\n{0}", p2pMessage.ToDebugString()), GetType().Name);

                // Keep RemoteID Synchronized, I think we must track remoteIdentifier here...
                // Send NAK??????
            }
        }
Beispiel #8
0
        internal bool HandleACK(P2PMessage p2pMessage)
        {
            bool isAckOrNak = false;

            if (p2pMessage.Header.IsAcknowledgement || p2pMessage.Header.IsNegativeAck)
            {
                P2PAckMessageEventArgs e = null;
                uint ackNakId            = 0;
                isAckOrNak = true;

                if (p2pMessage.Version == P2PVersion.P2PV1)
                {
                    lock (ackHandlersV1)
                    {
                        if (ackHandlersV1.ContainsKey(p2pMessage.Header.AckIdentifier))
                        {
                            ackNakId = p2pMessage.Header.AckIdentifier;
                            e        = ackHandlersV1[ackNakId];
                            ackHandlersV1.Remove(ackNakId);
                        }
                    }
                }
                else if (p2pMessage.Version == P2PVersion.P2PV2)
                {
                    lock (ackHandlersV2)
                    {
                        if (ackHandlersV2.ContainsKey(p2pMessage.Header.AckIdentifier))
                        {
                            ackNakId = p2pMessage.Header.AckIdentifier;
                            e        = ackHandlersV2[ackNakId];
                            ackHandlersV2.Remove(ackNakId);
                        }
                        else if (ackHandlersV2.ContainsKey(p2pMessage.V2Header.NakIdentifier))
                        {
                            ackNakId = p2pMessage.V2Header.NakIdentifier;
                            e        = ackHandlersV2[ackNakId];
                            ackHandlersV2.Remove(ackNakId);
                        }
                    }
                }

                if (ackNakId == 0)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                      String.Format("!!!!!! No AckHandler registered for ack/nak {0}:\r\n{1}", p2pMessage.Header.AckIdentifier, p2pMessage.ToDebugString()), GetType().Name);
                }
                else
                {
                    if (e != null && e.AckHandler != null)
                    {
                        e.AckHandler(p2pMessage);
                    }
                    else
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                          String.Format("!!!!!! No AckHandler pair for ack {0}\r\n{1}", ackNakId, p2pMessage.ToDebugString()), GetType().Name);
                    }
                }
            }

            return(isAckOrNak);
        }