Пример #1
0
        /// <summary>
        /// Creates a new session initiated locally and prepares the invitation message.
        /// The next step must be Invite().
        /// </summary>
        public P2PSession(P2PApplication app)
        {
            p2pApplication = app;
            version        = app.P2PVersion;

            localContact            = app.Local;
            remoteContact           = app.Remote;
            localContactEndPointID  = NSMessageHandler.MachineGuid;
            remoteContactEndPointID = app.Remote.SelectBestEndPointId();

            nsMessageHandler = app.Local.NSMessageHandler;
            sessionId        = (uint)random.Next(50000, int.MaxValue);

            // These 2 fields are set when optimal bridge found.
            localBaseIdentifier = 0;
            localIdentifier     = 0;

            invitation                         = new SLPRequestMessage(RemoteContactEPIDString, MSNSLPRequestMethod.INVITE);
            invitation.Target                  = RemoteContactEPIDString;
            invitation.Source                  = LocalContactEPIDString;
            invitation.ContentType             = "application/x-msnmsgr-sessionreqbody";
            invitation.BodyValues["SessionID"] = SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);
            app.SetupInviteMessage(invitation);

            app.P2PSession = this; // Register events
            remoteContact.DirectBridgeEstablished += RemoteDirectBridgeEstablished;

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

            status = P2PSessionStatus.WaitingForRemote;
            // Next step must be: Invite()
        }
Пример #2
0
        internal bool SendDirectInvite()
        {
            // Skip if we're currently using a TCPBridge.
            if (Remote.DirectBridge != null && Remote.DirectBridge.IsOpen)
            {
                return(false);
            }

            int        netId;
            string     connectionType = ConnectionType(nsMessageHandler, out netId);
            P2PMessage p2pMessage     = new P2PMessage(Version);

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                              String.Format("Connection type set to {0} for session {1}", connectionType, SessionId.ToString()));

            // Create the message
            SLPRequestMessage slpMessage = new SLPRequestMessage(RemoteContactEPIDString, MSNSLPRequestMethod.INVITE);

            slpMessage.Source      = LocalContactEPIDString;
            slpMessage.CSeq        = 0;
            slpMessage.CallId      = Invitation.CallId;
            slpMessage.MaxForwards = 0;
            slpMessage.ContentType = "application/x-msnmsgr-transreqbody";

            slpMessage.BodyValues["Bridges"]            = "TCPv1 SBBridge";
            slpMessage.BodyValues["Capabilities-Flags"] = "1";
            slpMessage.BodyValues["NetID"]             = netId.ToString(CultureInfo.InvariantCulture);
            slpMessage.BodyValues["Conn-Type"]         = connectionType;
            slpMessage.BodyValues["TCP-Conn-Type"]     = connectionType;
            slpMessage.BodyValues["UPnPNat"]           = "false";                                   // UPNP Enabled
            slpMessage.BodyValues["ICF"]               = (connectionType == "Firewall").ToString(); // Firewall enabled
            slpMessage.BodyValues["Nat-Trav-Msg-Type"] = "WLX-Nat-Trav-Msg-Direct-Connect-Req";

            // We support Hashed-Nonce ( 2 way handshake )
            Remote.GenerateNewDCKeys();
            slpMessage.BodyValues["Hashed-Nonce"] = Remote.dcLocalHashedNonce.ToString("B").ToUpper(CultureInfo.InvariantCulture);

            p2pMessage.InnerMessage = slpMessage;

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

            // These 3 step is very important...
            // 1- Stop sending for this session on sdgbridge until we receive a response to the direct invite or the timeout expires
            nsMessageHandler.SDGBridge.StopSending(this);
            // 2- Setup a dc timer.
            SetupDCTimer();
            // 3- Don't pass p2psession to the sdg bridge. Because, sdgbridge stopped this session.
            nsMessageHandler.SDGBridge.Send(null /*must be null to bypass queueing*/,
                                            Remote, RemoteContactEndPointID, p2pMessage);

            return(true);
        }
Пример #3
0
        /// <summary>
        /// Closes the session.
        /// </summary>
        public void Close()
        {
            if (status == P2PSessionStatus.Closing)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("P2PSession {0} was already closing, forcing unclean closure", SessionId), GetType().Name);

                OnClosed(new ContactEventArgs(Local));
            }
            else
            {
                OnClosing(new ContactEventArgs(Local));

                SLPRequestMessage slpMessage = new SLPRequestMessage(RemoteContactEPIDString, "BYE");
                slpMessage.Target                  = RemoteContactEPIDString;
                slpMessage.Source                  = LocalContactEPIDString;
                slpMessage.Branch                  = invitation.Branch;
                slpMessage.CallId                  = invitation.CallId;
                slpMessage.MaxForwards             = 0;
                slpMessage.ContentType             = "application/x-msnmsgr-sessionclosebody";
                slpMessage.BodyValues["SessionID"] = SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);

                P2PMessage p2pMessage = new P2PMessage(Version);
                if (version == P2PVersion.P2PV1)
                {
                    p2pMessage.V1Header.Flags = P2PFlag.MSNSLPInfo;
                }
                else if (version == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.OperationCode = (byte)OperationCode.RAK;
                    p2pMessage.V2Header.TFCombination = TFCombination.First;
                    p2pMessage.V2Header.PackageNumber = ++p2pBridge.PackageNo;
                }

                p2pMessage.InnerMessage = slpMessage;

                Send(p2pMessage, delegate(P2PMessage ack)
                {
                    OnClosed(new ContactEventArgs(Local));
                });
            }
        }
Пример #4
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();
        }
Пример #5
0
        internal bool SendDirectInvite()
        {
            // Skip if we're currently using a TCPBridge.
            if (Remote.DirectBridge != null && Remote.DirectBridge.IsOpen)
                return false;

            int netId;
            string connectionType = ConnectionType(nsMessageHandler, out netId);
            P2PMessage p2pMessage = new P2PMessage(Version);

            Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo,
                String.Format("Connection type set to {0} for session {1}", connectionType, SessionId.ToString()));

            // Create the message
            SLPRequestMessage slpMessage = new SLPRequestMessage(RemoteContactEPIDString, MSNSLPRequestMethod.INVITE);
            slpMessage.Source = LocalContactEPIDString;
            slpMessage.CSeq = 0;
            slpMessage.CallId = Invitation.CallId;
            slpMessage.MaxForwards = 0;
            slpMessage.ContentType = "application/x-msnmsgr-transreqbody";

            slpMessage.BodyValues["Bridges"] = "TCPv1 SBBridge";
            slpMessage.BodyValues["Capabilities-Flags"] = "1";
            slpMessage.BodyValues["NetID"] = netId.ToString(CultureInfo.InvariantCulture);
            slpMessage.BodyValues["Conn-Type"] = connectionType;
            slpMessage.BodyValues["TCP-Conn-Type"] = connectionType;
            slpMessage.BodyValues["UPnPNat"] = "false"; // UPNP Enabled
            slpMessage.BodyValues["ICF"] = (connectionType == "Firewall").ToString(); // Firewall enabled
            slpMessage.BodyValues["Nat-Trav-Msg-Type"] = "WLX-Nat-Trav-Msg-Direct-Connect-Req";

            // We support Hashed-Nonce ( 2 way handshake )
            Remote.GenerateNewDCKeys();
            slpMessage.BodyValues["Hashed-Nonce"] = Remote.dcLocalHashedNonce.ToString("B").ToUpper(CultureInfo.InvariantCulture);

            p2pMessage.InnerMessage = slpMessage;

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

            // These 3 step is very important...
            // 1- Stop sending for this session on sdgbridge until we receive a response to the direct invite or the timeout expires
            nsMessageHandler.SDGBridge.StopSending(this);
            // 2- Setup a dc timer.
            SetupDCTimer();
            // 3- Don't pass p2psession to the sdg bridge. Because, sdgbridge stopped this session.
            nsMessageHandler.SDGBridge.Send(null /*must be null to bypass queueing*/,
                Remote, RemoteContactEndPointID, p2pMessage);

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

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

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

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

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

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

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

            remoteContact.DirectBridgeEstablished += RemoteDirectBridgeEstablished;

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

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

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

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

            if (p2pApplication != null && p2pApplication.ValidateInvitation(invitation))
            {
                if (p2pApplication.AutoAccept)
                {
                    Accept();
                }
                else
                {
                    ns.P2PHandler.OnInvitationReceived(new P2PSessionEventArgs(this));
                }
            }
            else
            {
                Decline();
            }
        }
Пример #8
0
        /// <summary>
        /// Closes the session.
        /// </summary>
        public void Close()
        {
            if (status == P2PSessionStatus.Closing)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                    String.Format("P2PSession {0} was already closing, forcing unclean closure", SessionId), GetType().Name);

                OnClosed(new ContactEventArgs(Local));
            }
            else
            {
                OnClosing(new ContactEventArgs(Local));

                SLPRequestMessage slpMessage = new SLPRequestMessage(RemoteContactEPIDString, "BYE");
                slpMessage.Target = RemoteContactEPIDString;
                slpMessage.Source = LocalContactEPIDString;
                slpMessage.Branch = invitation.Branch;
                slpMessage.CallId = invitation.CallId;
                slpMessage.MaxForwards = 0;
                slpMessage.ContentType = "application/x-msnmsgr-sessionclosebody";
                slpMessage.BodyValues["SessionID"] = SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);

                P2PMessage p2pMessage = new P2PMessage(Version);
                if (version == P2PVersion.P2PV1)
                {
                    p2pMessage.V1Header.Flags = P2PFlag.MSNSLPInfo;
                }
                else if (version == P2PVersion.P2PV2)
                {
                    p2pMessage.V2Header.OperationCode = (byte)OperationCode.RAK;
                    p2pMessage.V2Header.TFCombination = TFCombination.First;
                    p2pMessage.V2Header.PackageNumber = ++p2pBridge.PackageNo;
                }

                p2pMessage.InnerMessage = slpMessage;

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

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

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

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

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

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

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

            remoteContact.DirectBridgeEstablished += RemoteDirectBridgeEstablished;

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

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

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

            if (p2pApplication != null && p2pApplication.ValidateInvitation(invitation))
            {
                if (p2pApplication.AutoAccept)
                {
                    Accept();
                }
                else
                {
                    ns.P2PHandler.OnInvitationReceived(new P2PSessionEventArgs(this));
                }
            }
            else
            {
                Decline();
            }
        }
Пример #10
0
        /// <summary>
        /// Creates a new session initiated locally and prepares the invitation message.
        /// The next step must be Invite().
        /// </summary>
        public P2PSession(P2PApplication app)
        {
            p2pApplication = app;
            version = app.P2PVersion;

            localContact = app.Local;
            remoteContact = app.Remote;
            localContactEndPointID = NSMessageHandler.MachineGuid;
            remoteContactEndPointID = app.Remote.SelectBestEndPointId();

            nsMessageHandler = app.Local.NSMessageHandler;
            sessionId = (uint)random.Next(50000, int.MaxValue);

            // These 2 fields are set when optimal bridge found.
            localBaseIdentifier = 0;
            localIdentifier = 0;

            invitation = new SLPRequestMessage(RemoteContactEPIDString, MSNSLPRequestMethod.INVITE);
            invitation.Target = RemoteContactEPIDString;
            invitation.Source = LocalContactEPIDString;
            invitation.ContentType = "application/x-msnmsgr-sessionreqbody";
            invitation.BodyValues["SessionID"] = SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);
            app.SetupInviteMessage(invitation);

            app.P2PSession = this; // Register events
            remoteContact.DirectBridgeEstablished += RemoteDirectBridgeEstablished;

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

            status = P2PSessionStatus.WaitingForRemote;
            // Next step must be: Invite()
        }
Пример #11
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);
        }
Пример #12
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();
            }
        }