Ejemplo n.º 1
0
        internal void SendSLPStatus(P2PBridge bridge, P2PMessage msg, Contact dest, Guid destGuid, int code, string phrase)
        {
            string target = dest.Account.ToLowerInvariant();

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

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

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

            P2PMessage response = new P2PMessage(msg.Version);

            response.InnerMessage = slp;

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

            bridge.Send(null, dest, destGuid, response);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Rejects the received invitation.
        /// </summary>
        public void Decline()
        {
            if (status != P2PSessionStatus.WaitingForLocal)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("Declined called, but we're not waiting for the local client (State {0})", status), GetType().Name);
            }
            else
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, String.Format("{0} declined", SessionId), GetType().Name);

                SLPStatusMessage slpMessage = new SLPStatusMessage(RemoteContactEPIDString, 603, "Decline");
                slpMessage.Target                  = RemoteContactEPIDString;
                slpMessage.Source                  = LocalContactEPIDString;
                slpMessage.Branch                  = invitation.Branch;
                slpMessage.CallId                  = invitation.CallId;
                slpMessage.CSeq                    = 1;
                slpMessage.ContentType             = "application/x-msnmsgr-sessionreqbody";
                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 = ++Bridge.PackageNo;
                }

                p2pMessage.InnerMessage = slpMessage;

                Send(p2pMessage);
                Close();
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Accepts the received invitation.
        /// </summary>
        public void Accept()
        {
            if (status != P2PSessionStatus.WaitingForLocal)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                  String.Format("Accept called, but we're not waiting for the local client (State {0})", status), GetType().Name);
            }
            else
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, String.Format("{0} accepted", SessionId), GetType().Name);

                SLPStatusMessage slpMessage = new SLPStatusMessage(RemoteContactEPIDString, 200, "OK");
                slpMessage.Target                  = RemoteContactEPIDString;
                slpMessage.Source                  = LocalContactEPIDString;
                slpMessage.Branch                  = invitation.Branch;
                slpMessage.CallId                  = invitation.CallId;
                slpMessage.CSeq                    = 1;
                slpMessage.ContentType             = "application/x-msnmsgr-sessionreqbody";
                slpMessage.BodyValues["SessionID"] = SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);

                Send(WrapSLPMessage(slpMessage), delegate(P2PMessage ack)
                {
                    OnActive(EventArgs.Empty);

                    if (p2pApplication != null)
                    {
                        p2pApplication.Start();
                    }
                    else
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                                          "Unable to start p2p application (null)", GetType().Name);
                    }
                });
            }
        }
Ejemplo n.º 4
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();
            }
        }
Ejemplo n.º 5
0
        internal void SendSLPStatus(P2PBridge bridge, P2PMessage msg, Contact dest, Guid destGuid, int code, string phrase)
        {
            string target = dest.Account.ToLowerInvariant();

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

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

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

            }
            else
                slp.ContentType = "null";

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

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

            bridge.Send(null, dest, destGuid, response);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Rejects the received invitation.
        /// </summary>
        public void Decline()
        {
            if (status != P2PSessionStatus.WaitingForLocal)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                    String.Format("Declined called, but we're not waiting for the local client (State {0})", status), GetType().Name);
            }
            else
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, String.Format("{0} declined", SessionId), GetType().Name);

                SLPStatusMessage slpMessage = new SLPStatusMessage(RemoteContactEPIDString, 603, "Decline");
                slpMessage.Target = RemoteContactEPIDString;
                slpMessage.Source = LocalContactEPIDString;
                slpMessage.Branch = invitation.Branch;
                slpMessage.CallId = invitation.CallId;
                slpMessage.CSeq = 1;
                slpMessage.ContentType = "application/x-msnmsgr-sessionreqbody";
                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 = ++Bridge.PackageNo;
                }

                p2pMessage.InnerMessage = slpMessage;

                Send(p2pMessage);
                Close();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Accepts the received invitation.
        /// </summary>
        public void Accept()
        {
            if (status != P2PSessionStatus.WaitingForLocal)
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                    String.Format("Accept called, but we're not waiting for the local client (State {0})", status), GetType().Name);
            }
            else
            {
                Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, String.Format("{0} accepted", SessionId), GetType().Name);

                SLPStatusMessage slpMessage = new SLPStatusMessage(RemoteContactEPIDString, 200, "OK");
                slpMessage.Target = RemoteContactEPIDString;
                slpMessage.Source = LocalContactEPIDString;
                slpMessage.Branch = invitation.Branch;
                slpMessage.CallId = invitation.CallId;
                slpMessage.CSeq = 1;
                slpMessage.ContentType = "application/x-msnmsgr-sessionreqbody";
                slpMessage.BodyValues["SessionID"] = SessionId.ToString(System.Globalization.CultureInfo.InvariantCulture);

                Send(WrapSLPMessage(slpMessage), delegate(P2PMessage ack)
                {
                    OnActive(EventArgs.Empty);

                    if (p2pApplication != null)
                    {
                        p2pApplication.Start();
                    }
                    else
                    {
                        Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning,
                            "Unable to start p2p application (null)", GetType().Name);
                    }

                });
            }
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
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();
                }
            }
        }