Beispiel #1
0
        /// <summary>
        /// We are sender
        /// </summary>
        /// <param name="p2pSession"></param>
        public ObjectTransfer(P2PSession p2pSession)
            : base(p2pSession)
        {
            msnObject = new MSNObject();
            msnObject.SetContext(p2pSession.Invitation.BodyValues["Context"].Value, true);

            if (msnObject.ObjectType == MSNObjectType.UserDisplay ||
                msnObject.ObjectType == MSNObjectType.Unknown)
            {
                msnObject = NSMessageHandler.Owner.DisplayImage;
                objStream = NSMessageHandler.Owner.DisplayImage.OpenStream();
            }
            else if (msnObject.ObjectType == MSNObjectType.Scene)
            {
                msnObject = NSMessageHandler.Owner.SceneImage;
                objStream = NSMessageHandler.Owner.SceneImage.OpenStream();
            }
            else if (msnObject.ObjectType == MSNObjectType.Emoticon &&
                Local.Emoticons.ContainsKey(msnObject.Sha))
            {
                msnObject = Local.Emoticons[msnObject.Sha];
                objStream = ((Emoticon)msnObject).OpenStream();
            }

            sending = true;

            if (p2pSession.Invitation.BodyValues.ContainsKey("AppID"))
                applicationId = uint.Parse(p2pSession.Invitation.BodyValues["AppID"]);
        }
Beispiel #2
0
        private static TCPv1Bridge ListenForDirectConnection(
            Contact remote,
            Guid remoteGuid,
            NSMessageHandler nsMessageHandler,
            P2PVersion ver,
            P2PSession startupSession,
            IPAddress host, int port, Guid replyGuid, Guid remoteNonce, bool hashed)
        {
            ConnectivitySettings cs = new ConnectivitySettings();

            if (nsMessageHandler.ConnectivitySettings.LocalHost == string.Empty)
            {
                cs.LocalHost = host.ToString();
                cs.LocalPort = port;
            }
            else
            {
                cs.LocalHost = nsMessageHandler.ConnectivitySettings.LocalHost;
                cs.LocalPort = nsMessageHandler.ConnectivitySettings.LocalPort;
            }

            TCPv1Bridge tcpBridge = new TCPv1Bridge(cs, ver, replyGuid, remoteNonce, hashed, startupSession, nsMessageHandler, remote, remoteGuid);

            tcpBridge.Listen(IPAddress.Parse(cs.LocalHost), cs.LocalPort);

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Listening on " + cs.LocalHost + ":" + cs.LocalPort.ToString(CultureInfo.InvariantCulture));

            return(tcpBridge);
        }
Beispiel #3
0
 protected virtual void SendMultiPacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage[] sendList)
 {
     foreach (P2PMessage p2pMessage in sendList)
     {
         SendOnePacket(session, remote, remoteGuid, p2pMessage);
     }
 }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnBridgeSent(P2PMessageSessionEventArgs e)
        {
            P2PSession session = e.P2PSession;

            lock (sendingQueues)
            {
                if ((session != null) && sendingQueues.ContainsKey(session))
                {
                    if (sendingQueues[session].Contains(e.P2PMessage))
                    {
                        sendingQueues[session].Remove(e.P2PMessage);
                    }
                    else
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                                          "Sent message not present in sending queue", GetType().Name);
                    }
                }
            }

            if (BridgeSent != null)
            {
                BridgeSent(this, e);
            }

            ProcessSendQueues();
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="session"></param>
        /// <param name="queue"></param>
        public virtual void AddQueue(P2PSession session, P2PSendQueue queue)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                              String.Format("P2PBridge {0} received queue for session {1}", this.ToString(), session.SessionId), GetType().Name);

            if (sendQueues.ContainsKey(session))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                                  "A queue is already present for this session, merging the queues", GetType().Name);

                lock (sendQueues[session])
                {
                    while (queue.Count > 0)
                    {
                        sendQueues[session].Enqueue(queue.Dequeue());
                    }
                }
            }
            else
            {
                lock (sendQueues)
                    sendQueues[session] = queue;
            }

            ProcessSendQueues();
        }
Beispiel #6
0
        public override bool SuitableFor(P2PSession session)
        {
            if (base.SuitableFor(session) && session.RemoteContactEndPointID == RemoteEpId)
            {
                return(true);
            }

            return(false);
        }
Beispiel #7
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);
            }
        }
        private P2PSession FindSession(P2PMessage msg, SLPMessage slp)
        {
            P2PSession p2pSession = null;
            uint       sessionID  = (msg != null) ? msg.Header.SessionId : 0;

            if ((sessionID == 0) && (slp != null))
            {
                if (slp.BodyValues.ContainsKey("SessionID"))
                {
                    if (!uint.TryParse(slp.BodyValues["SessionID"].Value, out sessionID))
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                          "Unable to parse SLP message SessionID", GetType().Name);

                        sessionID = 0;
                    }
                }

                if (sessionID == 0)
                {
                    // We don't get a session ID in BYE requests
                    // So we need to find the session by its call ID
                    P2PVersion p2pVersion = slp.P2PVersion;
                    p2pSession = FindSessionByCallId(slp.CallId, p2pVersion);

                    if (p2pSession != null)
                    {
                        return(p2pSession);
                    }
                }
            }

            // Sometimes we only have a messageID to find the session with...
            if ((sessionID == 0) && (msg.Header.Identifier != 0))
            {
                p2pSession = FindSessionByExpectedIdentifier(msg);

                if (p2pSession != null)
                {
                    return(p2pSession);
                }
            }

            if (sessionID != 0)
            {
                p2pSession = FindSessionBySessionId(sessionID, msg.Version);

                if (p2pSession != null)
                {
                    return(p2pSession);
                }
            }

            return(null);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        /// <summary>
        /// Send a P2P Message to the specified P2PSession.
        /// </summary>
        /// <param name="session">
        /// The application layer, which is a <see cref="P2PSession"/>
        /// </param>
        /// <param name="remote">
        /// he receiver <see cref="Contact"/>
        /// </param>
        /// <param name="remoteGuid">
        /// A <see cref="Guid"/>
        /// </param>
        /// <param name="msg">
        /// he <see cref="P2PMessage"/> to be sent.
        /// </param>
        /// <param name="ackTimeout">
        /// The maximum time to wait for an ACK. <see cref="System.Int32"/>
        /// </param>
        /// <param name="ackHandler">
        /// The <see cref="AckHandler"/> to handle the ACK.
        /// </param>
        public virtual void Send(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg, int ackTimeout, AckHandler ackHandler)
        {
            if (remote == null)
            {
                throw new ArgumentNullException("remote");
            }

            P2PMessage[] msgs = SetSequenceNumberAndRegisterAck(session, remote, msg, ackHandler, ackTimeout);

            if (session == null)
            {
                if (!IsOpen)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                                      "Send called with no session on a closed bridge", GetType().Name);

                    return;
                }

                // Bypass queueing
                foreach (P2PMessage m in msgs)
                {
                    SendOnePacket(null, remote, remoteGuid, m);
                }

                return;
            }

            if (!SuitableFor(session))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                                  "Send called with a session this bridge is not suitable for", GetType().Name);
                return;
            }

            lock (sendQueues)
            {
                if (!sendQueues.ContainsKey(session))
                {
                    sendQueues[session] = new P2PSendQueue();
                }
            }
            lock (sendQueues[session])
            {
                foreach (P2PMessage m in msgs)
                {
                    sendQueues[session].Enqueue(remote, remoteGuid, m);
                }
            }

            ProcessSendQueues();
        }
Beispiel #11
0
        private static void ProcessDirectAddrUpdate(
            SLPMessage message,
            NSMessageHandler nsMessageHandler,
            P2PSession startupSession)
        {
            Contact from = nsMessageHandler.ContactList.GetContactWithCreate(message.FromEmailAccount, IMAddressInfoType.WindowsLive);

            IPEndPoint[] ipEndPoints = SelectIPEndPoint(message.BodyValues, nsMessageHandler);

            if (from.DirectBridge != null && ipEndPoints != null && ipEndPoints.Length > 0)
            {
                ((TCPv1Bridge)from.DirectBridge).OnDestinationAddressUpdated(new DestinationAddressUpdatedEventArgs(ipEndPoints));
            }
        }
Beispiel #12
0
 /// <summary>
 /// Stop sending future messages to the specified <see cref="P2PSession"/>.
 /// </summary>
 /// <param name="session"></param>
 public virtual void StopSending(P2PSession session)
 {
     Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                       String.Format("P2PBridge {0} stop sending for {1}", this.ToString(), session.SessionId), GetType().Name);
     lock (stoppedSessions)
     {
         if (!stoppedSessions.Contains(session))
         {
             stoppedSessions.Add(session);
         }
         else
         {
             Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Session is already in stopped list", GetType().Name);
         }
     }
 }
Beispiel #13
0
        private P2PMessage[] SetSequenceNumberAndRegisterAck(P2PSession session, Contact remote, P2PMessage p2pMessage, AckHandler ackHandler, int timeout)
        {
            if (p2pMessage.Header.Identifier == 0)
            {
                if (p2pMessage.Version == P2PVersion.P2PV1)
                {
                    p2pMessage.Header.Identifier = ++sequenceId;
                }
                else if (p2pMessage.Version == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.Identifier = sequenceId;
                }
            }

            if (p2pMessage.Version == P2PVersion.P2PV1 && p2pMessage.V1Header.AckSessionId == 0)
            {
                p2pMessage.V1Header.AckSessionId = (uint)new Random().Next(50000, int.MaxValue);
            }
            if (p2pMessage.Version == P2PVersion.P2PV2 && p2pMessage.V2Header.PackageNumber == 0)
            {
                p2pMessage.V2Header.PackageNumber = packageNo;
            }

            P2PMessage[] msgs = p2pMessage.SplitMessage(MaxDataSize);

            if (p2pMessage.Version == P2PVersion.P2PV2)
            {
                // Correct local sequence no
                P2PMessage lastMsg = msgs[msgs.Length - 1];
                SequenceId = lastMsg.V2Header.Identifier + lastMsg.V2Header.MessageSize;
            }

            if (ackHandler != null)
            {
                P2PMessage firstMessage = msgs[0];
                RegisterAckHandler(new P2PAckMessageEventArgs(firstMessage, ackHandler, timeout));
            }

            if (session != null)
            {
                session.LocalIdentifier = SequenceId;
            }

            return(msgs);
        }
Beispiel #14
0
        /// <summary>
        /// Continue to send future messages to the specified <see cref="P2PSession"/>.
        /// </summary>
        /// <param name="session"></param>
        public virtual void ResumeSending(P2PSession session)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                              String.Format("P2PBridge {0} resume sending for {1}", this.ToString(), session.SessionId), GetType().Name);
            lock (stoppedSessions)
            {
                if (stoppedSessions.Contains(session))
                {
                    stoppedSessions.Remove(session);

                    ProcessSendQueues();
                }
                else
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Session not present in stopped list", GetType().Name);
                }
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        public P2PDirectProcessor(
            ConnectivitySettings connectivitySettings,
            P2PVersion p2pVersion,
            Guid reply, Guid authNonce, bool isNeedHash,
            P2PSession p2pMessageSession,
            NSMessageHandler nsMessageHandler)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Constructing object - " + p2pVersion, GetType().Name);

            Processor = new TcpSocketMessageProcessor(connectivitySettings, new P2PDCPool());

            this.version          = p2pVersion;
            this.nonce            = authNonce;
            this.reply            = reply;
            this.needHash         = isNeedHash;
            this.startupSession   = p2pMessageSession;
            this.nsMessageHandler = nsMessageHandler;
        }
Beispiel #16
0
        public P2PSession AddTransfer(P2PApplication app)
        {
            P2PSession session = new P2PSession(app);

            session.Closed += P2PSessionClosed;

            if (app.P2PVersion == P2PVersion.P2PV2)
            {
                p2pV2Sessions.Add(session);
            }
            else
            {
                p2pV1Sessions.Add(session);
            }

            session.Invite();

            return(session);
        }
Beispiel #17
0
        private void P2PSessionClosed(object sender, ContactEventArgs args)
        {
            P2PSession session = sender as P2PSession;

            session.Closed -= P2PSessionClosed;

            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                              String.Format("P2PSession {0} closed, removing", session.SessionId), GetType().Name);

            if (session.Version == P2PVersion.P2PV2)
            {
                p2pV2Sessions.Remove(session);
            }
            else
            {
                p2pV1Sessions.Remove(session);
            }

            session.Dispose();
        }
Beispiel #18
0
        /// <summary>
        /// Check if the session is ready to begin sending packets.
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        public virtual bool Ready(P2PSession session)
        {
            lock (stoppedSessions)
            {
                if (queueSize == 0)
                {
                    return(IsOpen && (!stoppedSessions.Contains(session)));
                }

                lock (sendingQueues)
                {
                    if (!sendingQueues.ContainsKey(session))
                    {
                        return(IsOpen && SuitableFor(session) && (!stoppedSessions.Contains(session)));
                    }

                    return(IsOpen && (sendingQueues[session].Count < queueSize) && (!stoppedSessions.Contains(session)));
                }
            }
        }
Beispiel #19
0
        internal P2PBridge GetBridge(P2PSession session)
        {
            foreach (P2PBridge existing in bridges)
            {
                if (existing.SuitableFor(session))
                {
                    return(existing);
                }
            }


            return(nsMessageHandler.SDGBridge);

            /*MSNP21TODO
             * P2PBridge bridge = new SBBridge(session);
             * bridge.BridgeClosed += BridgeClosed;
             *
             * bridges.Add(bridge);
             *
             * return bridge;
             * */
        }
Beispiel #20
0
        public TCPv1Bridge(
            ConnectivitySettings connectivitySettings,
            P2PVersion p2pVersion,
            Guid replyNonce, Guid remoteNonce, bool isNeedHash,
            P2PSession p2pSession,
            NSMessageHandler ns,
            Contact remote, Guid remoteEpId)
            : base(0, ns)
        {
            this.startupSession = p2pSession;
            this.remote         = remote;
            this.remoteEpId     = remoteEpId;

            directConnection = new P2PDirectProcessor(connectivitySettings, p2pVersion, replyNonce, remoteNonce, isNeedHash, p2pSession, ns);
            directConnection.HandshakeCompleted += new EventHandler <EventArgs>(directConnection_HandshakeCompleted);
            directConnection.P2PMessageReceived += new EventHandler <P2PMessageEventArgs>(directConnection_P2PMessageReceived);
            directConnection.SendCompleted      += new EventHandler <MSNPSharp.Core.ObjectEventArgs>(directConnection_SendCompleted);

            directConnection.DirectNegotiationTimedOut += new EventHandler <EventArgs>(directConnection_DirectNegotiationTimedOut);
            directConnection.ConnectionClosed          += new EventHandler <EventArgs>(directConnection_ConnectionClosed);
            directConnection.ConnectingException       += new EventHandler <ExceptionEventArgs>(directConnection_ConnectingException);
            directConnection.ConnectionException       += new EventHandler <ExceptionEventArgs>(directConnection_ConnectionException);
        }
Beispiel #21
0
        public P2PActivity(P2PSession p2pSess)
            : base(p2pSess.Version, p2pSess.Remote, p2pSess.RemoteContactEndPointID)
        {
            try
            {
                byte[] byts = Convert.FromBase64String(p2pSess.Invitation.BodyValues["Context"].Value);
                string activityUrl = System.Text.Encoding.Unicode.GetString(byts);
                string[] activityProperties = activityUrl.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                if (activityProperties.Length >= 3)
                {
                    uint.TryParse(activityProperties[0], out applicationId);
                    activityName = activityProperties[2];
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                    "An error occured while parsing activity context, error info: " +
                    ex.Message, GetType().Name);
            }

            sending = false;
        }
Beispiel #22
0
 protected override void SendOnePacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg)
 {
     directConnection.SendMessage(msg, new P2PMessageSessionEventArgs(msg, session));
 }
Beispiel #23
0
        private static void ProcessDirectAddrUpdate(
            SLPMessage message,
            NSMessageHandler nsMessageHandler,
            P2PSession startupSession)
        {
            Contact from = nsMessageHandler.ContactList.GetContactWithCreate(message.FromEmailAccount, IMAddressInfoType.WindowsLive);
            IPEndPoint[] ipEndPoints = SelectIPEndPoint(message.BodyValues, nsMessageHandler);

            if (from.DirectBridge != null && ipEndPoints != null && ipEndPoints.Length > 0)
            {
                ((TCPv1Bridge)from.DirectBridge).OnDestinationAddressUpdated(new DestinationAddressUpdatedEventArgs(ipEndPoints));
            }
        }
Beispiel #24
0
        private static TCPv1Bridge CreateDirectConnection(Contact remote, Guid remoteGuid, P2PVersion ver, ConnectivitySettings cs, Guid replyGuid, Guid remoteNonce, bool hashed, NSMessageHandler nsMessageHandler, P2PSession startupSession)
        {
            string[] points = new string[cs.EndPoints.Length];

            for (int i = 0; i < points.Length; i++)
            {
                points[i] = cs.EndPoints[i].ToString();
            }

            TCPv1Bridge tcpBridge = new TCPv1Bridge(cs, ver, replyGuid, remoteNonce, hashed, startupSession, nsMessageHandler, remote, remoteGuid);

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Trying to setup direct connection with remote hosts " + string.Join(",", points));

            tcpBridge.Connect();

            return tcpBridge;
        }
Beispiel #25
0
        private static void ProcessDCReqInvite(SLPMessage message, NSMessageHandler ns, P2PSession startupSession)
        {
            if (startupSession != null && startupSession.Bridge != null &&
                startupSession.Bridge is TCPv1Bridge)
            {
                return; // We are using a dc bridge already. Don't allow second one.
            }

            if (message.BodyValues.ContainsKey("Bridges") &&
                message.BodyValues["Bridges"].ToString().Contains("TCPv1"))
            {
                SLPStatusMessage slpMessage = new SLPStatusMessage(message.Source, 200, "OK");
                slpMessage.Target = message.Source;
                slpMessage.Source = message.Target;
                slpMessage.Branch = message.Branch;
                slpMessage.CSeq = 1;
                slpMessage.CallId = message.CallId;
                slpMessage.MaxForwards = 0;
                slpMessage.ContentType = "application/x-msnmsgr-transrespbody";
                slpMessage.BodyValues["Bridge"] = "TCPv1";

                Guid remoteGuid = message.FromEndPoint;
                Contact remote = ns.ContactList.GetContactWithCreate(message.FromEmailAccount, IMAddressInfoType.WindowsLive);

                DCNonceType dcNonceType;
                Guid remoteNonce = ParseDCNonce(message.BodyValues, out dcNonceType);
                if (remoteNonce == Guid.Empty) // Plain
                    remoteNonce = remote.dcPlainKey;

                bool hashed = (dcNonceType == DCNonceType.Sha1);
                string nonceFieldName = hashed ? "Hashed-Nonce" : "Nonce";
                Guid myHashedNonce = hashed ? remote.dcLocalHashedNonce : remoteNonce;
                Guid myPlainNonce = remote.dcPlainKey;
                if (dcNonceType == DCNonceType.Sha1)
                {
                    // Remote contact supports Hashed-Nonce
                    remote.dcType = dcNonceType;
                    remote.dcRemoteHashedNonce = remoteNonce;
                }
                else
                {
                    remote.dcType = DCNonceType.Plain;
                    myPlainNonce = remote.dcPlainKey = remote.dcLocalHashedNonce = remote.dcRemoteHashedNonce = remoteNonce;
                }

                // Find host by name
                IPAddress ipAddress = ns.LocalEndPoint.Address;
                int port;

                P2PVersion ver = message.P2PVersion;

                if (Settings.DisableP2PDirectConnections ||
                    false == ipAddress.Equals(ns.ExternalEndPoint.Address) ||
                    (0 == (port = GetNextDirectConnectionPort(ipAddress))))
                {
                    slpMessage.BodyValues["Listening"] = "false";
                    slpMessage.BodyValues[nonceFieldName] = Guid.Empty.ToString("B").ToUpper(CultureInfo.InvariantCulture);
                }
                else
                {
                    // Let's listen
                    remote.DirectBridge = ListenForDirectConnection(remote, remoteGuid, ns, ver, startupSession, ipAddress, port, myPlainNonce, remoteNonce, hashed);

                    slpMessage.BodyValues["Listening"] = "true";
                    slpMessage.BodyValues["Capabilities-Flags"] = "1";
                    slpMessage.BodyValues["IPv6-global"] = string.Empty;
                    slpMessage.BodyValues["Nat-Trav-Msg-Type"] = "WLX-Nat-Trav-Msg-Direct-Connect-Resp";
                    slpMessage.BodyValues["UPnPNat"] = "false";

                    slpMessage.BodyValues["NeedConnectingEndpointInfo"] = "true";

                    slpMessage.BodyValues["Conn-Type"] = "Direct-Connect";
                    slpMessage.BodyValues["TCP-Conn-Type"] = "Direct-Connect";
                    slpMessage.BodyValues[nonceFieldName] = myHashedNonce.ToString("B").ToUpper(CultureInfo.InvariantCulture);
                    slpMessage.BodyValues["IPv4Internal-Addrs"] = ipAddress.ToString();
                    slpMessage.BodyValues["IPv4Internal-Port"] = port.ToString(CultureInfo.InvariantCulture);

                    // check if client is behind firewall (NAT-ted)
                    // if so, send the public ip also the client, so it can try to connect to that ip
                    if (!ns.ExternalEndPoint.Address.Equals(ns.LocalEndPoint.Address))
                    {
                        slpMessage.BodyValues["IPv4External-Addrs"] = ns.ExternalEndPoint.Address.ToString();
                        slpMessage.BodyValues["IPv4External-Port"] = port.ToString(CultureInfo.InvariantCulture);
                    }
                }

                P2PMessage p2pMessage = new P2PMessage(ver);
                p2pMessage.InnerMessage = slpMessage;

                if (ver == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.TFCombination = TFCombination.First;
                }
                else if (ver == P2PVersion.P2PV1)
                {
                    p2pMessage.V1Header.Flags = P2PFlag.MSNSLPInfo;
                }

                if (startupSession != null)
                {
                    startupSession.SetupDCTimer();
                    startupSession.Bridge.Send(null, startupSession.Remote, startupSession.RemoteContactEndPointID, p2pMessage);
                }
                else
                {
                    ns.SDGBridge.Send(null, remote, remoteGuid, p2pMessage);
                }
            }
            else
            {
                if (startupSession != null)
                    startupSession.DirectNegotiationFailed();
            }
        }
Beispiel #26
0
 protected abstract void SendOnePacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg);
Beispiel #27
0
        /// <summary>
        /// Creates a new P2PApplication instance with the parameters provided.
        /// </summary>
        /// <param name="eufGuid"></param>
        /// <param name="appId"></param>
        /// <param name="withSession"></param>
        internal static P2PApplication CreateInstance(Guid eufGuid, uint appId, P2PSession withSession)
        {
            if (withSession != null && eufGuid != Guid.Empty && p2pAppCache.ContainsKey(eufGuid))
            {
                if (appId != 0)
                {
                    foreach (P2PApp app in p2pAppCache[eufGuid])
                    {
                        if (appId == app.AppId)
                            return (P2PApplication)Activator.CreateInstance(app.AppType, withSession);
                    }
                }

                return (P2PApplication)Activator.CreateInstance(p2pAppCache[eufGuid][0].AppType, withSession);
            }

            return null;
        }
Beispiel #28
0
        private P2PMessage[] SetSequenceNumberAndRegisterAck(P2PSession session, Contact remote, P2PMessage p2pMessage, AckHandler ackHandler, int timeout)
        {
            if (p2pMessage.Header.Identifier == 0)
            {
                if (p2pMessage.Version == P2PVersion.P2PV1)
                {
                    p2pMessage.Header.Identifier = ++sequenceId;
                }
                else if (p2pMessage.Version == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.Identifier = sequenceId;
                }
            }

            if (p2pMessage.Version == P2PVersion.P2PV1 && p2pMessage.V1Header.AckSessionId == 0)
            {
                p2pMessage.V1Header.AckSessionId = (uint)new Random().Next(50000, int.MaxValue);
            }
            if (p2pMessage.Version == P2PVersion.P2PV2 && p2pMessage.V2Header.PackageNumber == 0)
            {
                p2pMessage.V2Header.PackageNumber = packageNo;
            }

            P2PMessage[] msgs = p2pMessage.SplitMessage(MaxDataSize);

            if (p2pMessage.Version == P2PVersion.P2PV2)
            {
                // Correct local sequence no
                P2PMessage lastMsg = msgs[msgs.Length - 1];
                SequenceId = lastMsg.V2Header.Identifier + lastMsg.V2Header.MessageSize;
            }

            if (ackHandler != null)
            {
                P2PMessage firstMessage = msgs[0];
                RegisterAckHandler(new P2PAckMessageEventArgs(firstMessage, ackHandler, timeout));
            }

            if (session != null)
            {
                session.LocalIdentifier = SequenceId;
            }

            return msgs;
        }
Beispiel #29
0
 public FileTransferForm(P2PSession p2pSess)
 {
     this.p2pSession = p2pSess;
     this.fileTransfer = p2pSess.Application as FileTransfer;
     InitializeComponent();
 }
Beispiel #30
0
 protected virtual void SendMultiPacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage[] sendList)
 {
     foreach (P2PMessage p2pMessage in sendList)
     {
         SendOnePacket(session, remote, remoteGuid, p2pMessage);
     }
 }
Beispiel #31
0
 protected abstract void SendOnePacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg);
Beispiel #32
0
        /// <summary>
        /// Check whether the P2P session can be transfer on the bridge. 
        /// </summary>
        /// <param name="session">
        /// The <see cref="P2PSession"/> needs to check.
        /// </param>
        /// <returns>
        /// A <see cref="System.Boolean"/>
        /// </returns>      
        public virtual bool SuitableFor(P2PSession session)
        {
            Contact remote = Remote;

            return (session != null) && (remote != null) && (session.Remote.IsSibling(remote));
        }
Beispiel #33
0
        /// <summary>
        /// Stop sending future messages to the specified <see cref="P2PSession"/>.
        /// </summary>
        /// <param name="session"></param>
        public virtual void StopSending(P2PSession session)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                String.Format("P2PBridge {0} stop sending for {1}", this.ToString(), session.SessionId), GetType().Name);
            lock (stoppedSessions)
            {
                if (!stoppedSessions.Contains(session))
                {

                    stoppedSessions.Add(session);
                }
                else
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Session is already in stopped list", GetType().Name);
            }
        }
Beispiel #34
0
        /// <summary>
        /// Send a P2P Message to the specified P2PSession. 
        /// </summary>
        /// <param name="session">
        /// The application layer, which is a <see cref="P2PSession"/>
        /// </param>
        /// <param name="remote">
        /// he receiver <see cref="Contact"/>
        /// </param>
        /// <param name="remoteGuid">
        /// A <see cref="Guid"/>
        /// </param>
        /// <param name="msg">
        /// he <see cref="P2PMessage"/> to be sent.
        /// </param>
        /// <param name="ackTimeout">
        /// The maximum time to wait for an ACK. <see cref="System.Int32"/>
        /// </param>
        /// <param name="ackHandler">
        /// The <see cref="AckHandler"/> to handle the ACK.
        /// </param>      
        public virtual void Send(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg, int ackTimeout, AckHandler ackHandler)
        {
            if (remote == null)
                throw new ArgumentNullException("remote");

            P2PMessage[] msgs = SetSequenceNumberAndRegisterAck(session, remote, msg, ackHandler, ackTimeout);

            if (session == null)
            {
                if (!IsOpen)
                {
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                        "Send called with no session on a closed bridge", GetType().Name);

                    return;
                }

                // Bypass queueing
                foreach (P2PMessage m in msgs)
                {
                    SendOnePacket(null, remote, remoteGuid, m);
                }

                return;
            }

            if (!SuitableFor(session))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceError,
                        "Send called with a session this bridge is not suitable for", GetType().Name);
                return;
            }

            lock (sendQueues)
            {
                if (!sendQueues.ContainsKey(session))
                    sendQueues[session] = new P2PSendQueue();
            }
            lock (sendQueues[session])
            {
                foreach (P2PMessage m in msgs)
                    sendQueues[session].Enqueue(remote, remoteGuid, m);
            }

            ProcessSendQueues();
        }
Beispiel #35
0
        private static void ProcessDCRespInvite(SLPMessage message, NSMessageHandler ns, P2PSession startupSession)
        {
            MimeDictionary bodyValues = message.BodyValues;

            // Check the protocol
            if (bodyValues.ContainsKey("Bridge") &&
                bodyValues["Bridge"].ToString() == "TCPv1" &&
                bodyValues.ContainsKey("Listening") &&
                bodyValues["Listening"].ToString().ToLowerInvariant().IndexOf("true") >= 0)
            {
                Contact remote     = ns.ContactList.GetContactWithCreate(message.FromEmailAccount, IMAddressInfoType.WindowsLive);
                Guid    remoteGuid = message.FromEndPoint;

                DCNonceType dcNonceType;
                Guid        remoteNonce = ParseDCNonce(message.BodyValues, out dcNonceType);
                bool        hashed      = (dcNonceType == DCNonceType.Sha1);
                Guid        replyGuid   = hashed ? remote.dcPlainKey : remoteNonce;

                IPEndPoint[] selectedPoint = SelectIPEndPoint(bodyValues, ns);

                if (selectedPoint != null && selectedPoint.Length > 0)
                {
                    P2PVersion ver = message.P2PVersion;

                    // We must connect to the remote client
                    ConnectivitySettings settings = new ConnectivitySettings();
                    settings.EndPoints  = selectedPoint;
                    remote.DirectBridge = CreateDirectConnection(remote, remoteGuid, ver, settings, replyGuid, remoteNonce, hashed, ns, startupSession);

                    bool needConnectingEndpointInfo;
                    if (bodyValues.ContainsKey("NeedConnectingEndpointInfo") &&
                        bool.TryParse(bodyValues["NeedConnectingEndpointInfo"], out needConnectingEndpointInfo) &&
                        needConnectingEndpointInfo == true)
                    {
                        IPEndPoint ipep = ((TCPv1Bridge)remote.DirectBridge).LocalEndPoint;

                        string desc = "stroPdnAsrddAlanretnI4vPI";
                        char[] rev  = ipep.ToString().ToCharArray();
                        Array.Reverse(rev);
                        string ipandport = new string(rev);

                        SLPRequestMessage slpResponseMessage = new SLPRequestMessage(message.Source, MSNSLPRequestMethod.ACK);
                        slpResponseMessage.Source      = message.Target;
                        slpResponseMessage.Via         = message.Via;
                        slpResponseMessage.CSeq        = 0;
                        slpResponseMessage.CallId      = Guid.Empty;
                        slpResponseMessage.MaxForwards = 0;
                        slpResponseMessage.ContentType = @"application/x-msnmsgr-transdestaddrupdate";

                        slpResponseMessage.BodyValues[desc] = ipandport;
                        slpResponseMessage.BodyValues["Nat-Trav-Msg-Type"] = "WLX-Nat-Trav-Msg-Updated-Connecting-Port";

                        P2PMessage msg = new P2PMessage(ver);
                        msg.InnerMessage = slpResponseMessage;

                        ns.SDGBridge.Send(null, remote, remoteGuid, msg);
                    }

                    return;
                }
            }

            if (startupSession != null)
            {
                startupSession.DirectNegotiationFailed();
            }
        }
Beispiel #36
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="session"></param>
        /// <param name="queue"></param>
        public virtual void AddQueue(P2PSession session, P2PSendQueue queue)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
               String.Format("P2PBridge {0} received queue for session {1}", this.ToString(), session.SessionId), GetType().Name);

            if (sendQueues.ContainsKey(session))
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                    "A queue is already present for this session, merging the queues", GetType().Name);

                lock (sendQueues[session])
                {
                    while (queue.Count > 0)
                        sendQueues[session].Enqueue(queue.Dequeue());
                }
            }
            else
            {
                lock (sendQueues)
                    sendQueues[session] = queue;
            }

            ProcessSendQueues();
        }
Beispiel #37
0
 /// <summary>
 /// Send a P2P Message to the specified P2PSession. 
 /// </summary>
 /// <param name="session">
 /// The application layer, which is a <see cref="P2PSession"/>.
 /// </param>
 /// <param name="remote">
 /// The receiver <see cref="Contact"/>.
 /// </param>
 /// <param name="remoteGuid">
 /// A <see cref="Guid"/>
 /// </param>
 /// <param name="msg">
 /// The <see cref="P2PMessage"/> to be sent.
 /// </param>      
 public virtual void Send(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg)
 {
     Send(session, remote, remoteGuid, msg, 0, null);
 }
Beispiel #38
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);
        }
Beispiel #39
0
        /// <summary>
        /// Check if the session is ready to begin sending packets.
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        public virtual bool Ready(P2PSession session)
        {
            lock (stoppedSessions)
            {
                if (queueSize == 0)
                    return IsOpen && (!stoppedSessions.Contains(session));

                lock (sendingQueues)
                {
                    if (!sendingQueues.ContainsKey(session))
                        return IsOpen && SuitableFor(session) && (!stoppedSessions.Contains(session));

                    return IsOpen && (sendingQueues[session].Count < queueSize) && (!stoppedSessions.Contains(session));
                }
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        public P2PDirectProcessor(
            ConnectivitySettings connectivitySettings,
            P2PVersion p2pVersion,
            Guid reply, Guid authNonce, bool isNeedHash,
            P2PSession p2pMessageSession,
            NSMessageHandler nsMessageHandler)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Constructing object - " + p2pVersion, GetType().Name);

            Processor = new TcpSocketMessageProcessor(connectivitySettings, new P2PDCPool());

            this.version = p2pVersion;
            this.nonce = authNonce;
            this.reply = reply;
            this.needHash = isNeedHash;
            this.startupSession = p2pMessageSession;
            this.nsMessageHandler = nsMessageHandler;
        }
Beispiel #41
0
        private static TCPv1Bridge CreateDirectConnection(Contact remote, Guid remoteGuid, P2PVersion ver, ConnectivitySettings cs, Guid replyGuid, Guid remoteNonce, bool hashed, NSMessageHandler nsMessageHandler, P2PSession startupSession)
        {
            string[] points = new string[cs.EndPoints.Length];

            for (int i = 0; i < points.Length; i++)
            {
                points[i] = cs.EndPoints[i].ToString();
            }

            TCPv1Bridge tcpBridge = new TCPv1Bridge(cs, ver, replyGuid, remoteNonce, hashed, startupSession, nsMessageHandler, remote, remoteGuid);

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Trying to setup direct connection with remote hosts " + string.Join(",", points));

            tcpBridge.Connect();

            return(tcpBridge);
        }
Beispiel #42
0
 public override bool SuitableFor(P2PSession session)
 {
     return true;
 }
Beispiel #43
0
        private static TCPv1Bridge ListenForDirectConnection(
            Contact remote,
            Guid remoteGuid,
            NSMessageHandler nsMessageHandler,
            P2PVersion ver,
            P2PSession startupSession,
            IPAddress host, int port, Guid replyGuid, Guid remoteNonce, bool hashed)
        {
            ConnectivitySettings cs = new ConnectivitySettings();
            if (nsMessageHandler.ConnectivitySettings.LocalHost == string.Empty)
            {
                cs.LocalHost = host.ToString();
                cs.LocalPort = port;
            }
            else
            {
                cs.LocalHost = nsMessageHandler.ConnectivitySettings.LocalHost;
                cs.LocalPort = nsMessageHandler.ConnectivitySettings.LocalPort;
            }

            TCPv1Bridge tcpBridge = new TCPv1Bridge(cs, ver, replyGuid, remoteNonce, hashed, startupSession, nsMessageHandler, remote, remoteGuid);

            tcpBridge.Listen(IPAddress.Parse(cs.LocalHost), cs.LocalPort);

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "Listening on " + cs.LocalHost + ":" + cs.LocalPort.ToString(CultureInfo.InvariantCulture));

            return tcpBridge;
        }
Beispiel #44
0
        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());
            }
        }
Beispiel #45
0
        private static void ProcessDCRespInvite(SLPMessage message, NSMessageHandler ns, P2PSession startupSession)
        {
            MimeDictionary bodyValues = message.BodyValues;

            // Check the protocol
            if (bodyValues.ContainsKey("Bridge") &&
                bodyValues["Bridge"].ToString() == "TCPv1" &&
                bodyValues.ContainsKey("Listening") &&
                bodyValues["Listening"].ToString().ToLowerInvariant().IndexOf("true") >= 0)
            {
                Contact remote = ns.ContactList.GetContactWithCreate(message.FromEmailAccount, IMAddressInfoType.WindowsLive);
                Guid remoteGuid = message.FromEndPoint;

                DCNonceType dcNonceType;
                Guid remoteNonce = ParseDCNonce(message.BodyValues, out dcNonceType);
                bool hashed = (dcNonceType == DCNonceType.Sha1);
                Guid replyGuid = hashed ? remote.dcPlainKey : remoteNonce;

                IPEndPoint[] selectedPoint = SelectIPEndPoint(bodyValues, ns);

                if (selectedPoint != null && selectedPoint.Length > 0)
                {
                    P2PVersion ver = message.P2PVersion;

                    // We must connect to the remote client
                    ConnectivitySettings settings = new ConnectivitySettings();
                    settings.EndPoints = selectedPoint;
                    remote.DirectBridge = CreateDirectConnection(remote, remoteGuid, ver, settings, replyGuid, remoteNonce, hashed, ns, startupSession);

                    bool needConnectingEndpointInfo;
                    if (bodyValues.ContainsKey("NeedConnectingEndpointInfo") &&
                        bool.TryParse(bodyValues["NeedConnectingEndpointInfo"], out needConnectingEndpointInfo) &&
                        needConnectingEndpointInfo == true)
                    {
                        IPEndPoint ipep = ((TCPv1Bridge)remote.DirectBridge).LocalEndPoint;

                        string desc = "stroPdnAsrddAlanretnI4vPI";
                        char[] rev = ipep.ToString().ToCharArray();
                        Array.Reverse(rev);
                        string ipandport = new string(rev);

                        SLPRequestMessage slpResponseMessage = new SLPRequestMessage(message.Source, MSNSLPRequestMethod.ACK);
                        slpResponseMessage.Source = message.Target;
                        slpResponseMessage.Via = message.Via;
                        slpResponseMessage.CSeq = 0;
                        slpResponseMessage.CallId = Guid.Empty;
                        slpResponseMessage.MaxForwards = 0;
                        slpResponseMessage.ContentType = @"application/x-msnmsgr-transdestaddrupdate";

                        slpResponseMessage.BodyValues[desc] = ipandport;
                        slpResponseMessage.BodyValues["Nat-Trav-Msg-Type"] = "WLX-Nat-Trav-Msg-Updated-Connecting-Port";

                        P2PMessage msg = new P2PMessage(ver);
                        msg.InnerMessage = slpResponseMessage;

                        ns.SDGBridge.Send(null, remote, remoteGuid, msg);
                    }

                    return;
                }
            }

            if (startupSession != null)
                startupSession.DirectNegotiationFailed();
        }
Beispiel #46
0
        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);
        }
Beispiel #47
0
        internal static void ProcessDirectInvite(SLPMessage slp, NSMessageHandler ns, P2PSession startupSession)
        {
            switch (slp.ContentType)
            {
                case "application/x-msnmsgr-transreqbody":
                    ProcessDCReqInvite(slp, ns, startupSession);
                    break;

                case "application/x-msnmsgr-transrespbody":
                    ProcessDCRespInvite(slp, ns, startupSession);
                    break;

                case "application/x-msnmsgr-transdestaddrupdate":
                    ProcessDirectAddrUpdate(slp, ns, startupSession);
                    break;
            }
        }
Beispiel #48
0
        internal static void ProcessDirectInvite(SLPMessage slp, NSMessageHandler ns, P2PSession startupSession)
        {
            switch (slp.ContentType)
            {
            case "application/x-msnmsgr-transreqbody":
                ProcessDCReqInvite(slp, ns, startupSession);
                break;

            case "application/x-msnmsgr-transrespbody":
                ProcessDCRespInvite(slp, ns, startupSession);
                break;

            case "application/x-msnmsgr-transdestaddrupdate":
                ProcessDirectAddrUpdate(slp, ns, startupSession);
                break;
            }
        }
Beispiel #49
0
        public override bool SuitableFor(P2PSession session)
        {
            if (base.SuitableFor(session) && session.RemoteContactEndPointID == RemoteEpId)
            {
                return true;
            }

            return false;
        }
Beispiel #50
0
 protected override void SendOnePacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg)
 {
     directConnection.SendMessage(msg, new P2PMessageSessionEventArgs(msg, session));
 }
Beispiel #51
0
        public TCPv1Bridge(
            ConnectivitySettings connectivitySettings,
            P2PVersion p2pVersion,
            Guid replyNonce, Guid remoteNonce, bool isNeedHash,
            P2PSession p2pSession,
            NSMessageHandler ns,
            Contact remote, Guid remoteEpId)
            : base(0, ns)
        {
            this.startupSession = p2pSession;
            this.remote = remote;
            this.remoteEpId = remoteEpId;

            directConnection = new P2PDirectProcessor(connectivitySettings, p2pVersion, replyNonce, remoteNonce, isNeedHash, p2pSession, ns);
            directConnection.HandshakeCompleted += new EventHandler<EventArgs>(directConnection_HandshakeCompleted);
            directConnection.P2PMessageReceived += new EventHandler<P2PMessageEventArgs>(directConnection_P2PMessageReceived);
            directConnection.SendCompleted += new EventHandler<MSNPSharp.Core.ObjectEventArgs>(directConnection_SendCompleted);

            directConnection.DirectNegotiationTimedOut += new EventHandler<EventArgs>(directConnection_DirectNegotiationTimedOut);
            directConnection.ConnectionClosed += new EventHandler<EventArgs>(directConnection_ConnectionClosed);
            directConnection.ConnectingException += new EventHandler<ExceptionEventArgs>(directConnection_ConnectingException);
            directConnection.ConnectionException += new EventHandler<ExceptionEventArgs>(directConnection_ConnectionException);
        }
Beispiel #52
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 #53
0
        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());
            }
        }
Beispiel #54
0
        /// <summary>
        /// Continue to send future messages to the specified <see cref="P2PSession"/>.
        /// </summary>
        /// <param name="session"></param>
        public virtual void ResumeSending(P2PSession session)
        {
            Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose,
                String.Format("P2PBridge {0} resume sending for {1}", this.ToString(), session.SessionId), GetType().Name);
            lock (stoppedSessions)
            {
                if (stoppedSessions.Contains(session))
                {
                    stoppedSessions.Remove(session);

                    ProcessSendQueues();
                }
                else
                    Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "Session not present in stopped list", GetType().Name);
            }
        }
Beispiel #55
0
        private static void ProcessDCReqInvite(SLPMessage message, NSMessageHandler ns, P2PSession startupSession)
        {
            if (startupSession != null && startupSession.Bridge != null &&
                startupSession.Bridge is TCPv1Bridge)
            {
                return; // We are using a dc bridge already. Don't allow second one.
            }

            if (message.BodyValues.ContainsKey("Bridges") &&
                message.BodyValues["Bridges"].ToString().Contains("TCPv1"))
            {
                SLPStatusMessage slpMessage = new SLPStatusMessage(message.Source, 200, "OK");
                slpMessage.Target               = message.Source;
                slpMessage.Source               = message.Target;
                slpMessage.Branch               = message.Branch;
                slpMessage.CSeq                 = 1;
                slpMessage.CallId               = message.CallId;
                slpMessage.MaxForwards          = 0;
                slpMessage.ContentType          = "application/x-msnmsgr-transrespbody";
                slpMessage.BodyValues["Bridge"] = "TCPv1";

                Guid    remoteGuid = message.FromEndPoint;
                Contact remote     = ns.ContactList.GetContactWithCreate(message.FromEmailAccount, IMAddressInfoType.WindowsLive);

                DCNonceType dcNonceType;
                Guid        remoteNonce = ParseDCNonce(message.BodyValues, out dcNonceType);
                if (remoteNonce == Guid.Empty) // Plain
                {
                    remoteNonce = remote.dcPlainKey;
                }

                bool   hashed         = (dcNonceType == DCNonceType.Sha1);
                string nonceFieldName = hashed ? "Hashed-Nonce" : "Nonce";
                Guid   myHashedNonce  = hashed ? remote.dcLocalHashedNonce : remoteNonce;
                Guid   myPlainNonce   = remote.dcPlainKey;
                if (dcNonceType == DCNonceType.Sha1)
                {
                    // Remote contact supports Hashed-Nonce
                    remote.dcType = dcNonceType;
                    remote.dcRemoteHashedNonce = remoteNonce;
                }
                else
                {
                    remote.dcType = DCNonceType.Plain;
                    myPlainNonce  = remote.dcPlainKey = remote.dcLocalHashedNonce = remote.dcRemoteHashedNonce = remoteNonce;
                }

                // Find host by name
                IPAddress ipAddress = ns.LocalEndPoint.Address;
                int       port;

                P2PVersion ver = message.P2PVersion;

                if (Settings.DisableP2PDirectConnections ||
                    false == ipAddress.Equals(ns.ExternalEndPoint.Address) ||
                    (0 == (port = GetNextDirectConnectionPort(ipAddress))))
                {
                    slpMessage.BodyValues["Listening"]    = "false";
                    slpMessage.BodyValues[nonceFieldName] = Guid.Empty.ToString("B").ToUpper(CultureInfo.InvariantCulture);
                }
                else
                {
                    // Let's listen
                    remote.DirectBridge = ListenForDirectConnection(remote, remoteGuid, ns, ver, startupSession, ipAddress, port, myPlainNonce, remoteNonce, hashed);

                    slpMessage.BodyValues["Listening"]          = "true";
                    slpMessage.BodyValues["Capabilities-Flags"] = "1";
                    slpMessage.BodyValues["IPv6-global"]        = string.Empty;
                    slpMessage.BodyValues["Nat-Trav-Msg-Type"]  = "WLX-Nat-Trav-Msg-Direct-Connect-Resp";
                    slpMessage.BodyValues["UPnPNat"]            = "false";

                    slpMessage.BodyValues["NeedConnectingEndpointInfo"] = "true";

                    slpMessage.BodyValues["Conn-Type"]          = "Direct-Connect";
                    slpMessage.BodyValues["TCP-Conn-Type"]      = "Direct-Connect";
                    slpMessage.BodyValues[nonceFieldName]       = myHashedNonce.ToString("B").ToUpper(CultureInfo.InvariantCulture);
                    slpMessage.BodyValues["IPv4Internal-Addrs"] = ipAddress.ToString();
                    slpMessage.BodyValues["IPv4Internal-Port"]  = port.ToString(CultureInfo.InvariantCulture);

                    // check if client is behind firewall (NAT-ted)
                    // if so, send the public ip also the client, so it can try to connect to that ip
                    if (!ns.ExternalEndPoint.Address.Equals(ns.LocalEndPoint.Address))
                    {
                        slpMessage.BodyValues["IPv4External-Addrs"] = ns.ExternalEndPoint.Address.ToString();
                        slpMessage.BodyValues["IPv4External-Port"]  = port.ToString(CultureInfo.InvariantCulture);
                    }
                }

                P2PMessage p2pMessage = new P2PMessage(ver);
                p2pMessage.InnerMessage = slpMessage;

                if (ver == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.TFCombination = TFCombination.First;
                }
                else if (ver == P2PVersion.P2PV1)
                {
                    p2pMessage.V1Header.Flags = P2PFlag.MSNSLPInfo;
                }

                if (startupSession != null)
                {
                    startupSession.SetupDCTimer();
                    startupSession.Bridge.Send(null, startupSession.Remote, startupSession.RemoteContactEndPointID, p2pMessage);
                }
                else
                {
                    ns.SDGBridge.Send(null, remote, remoteGuid, p2pMessage);
                }
            }
            else
            {
                if (startupSession != null)
                {
                    startupSession.DirectNegotiationFailed();
                }
            }
        }
Beispiel #56
0
 public override bool SuitableFor(P2PSession session)
 {
     return(true);
 }
Beispiel #57
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;
        }
Beispiel #58
0
        protected P2PApplication(P2PSession p2pSess)
            : this(p2pSess.Version, p2pSess.Remote, p2pSess.RemoteContactEndPointID)
        {
            P2PSession = p2pSess; // Register events

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                "Application associated with session: " + p2pSess.SessionId, GetType().Name);
        }
Beispiel #59
0
 public P2PSessionEventArgs(P2PSession session)
 {
     this.p2pSession = session;
 }
Beispiel #60
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);
        }