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); }
/// <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(); } }
/// <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); } }); } }
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(); } }
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); }
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); }
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(); } } }