public void TellRemoteEndToUseThisPair(RTPStream stream, string strUsername, string strPassword) { if (IsControlling == false) { throw new Exception("Only controlling endpoint can send a usecandidate attribute"); } STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; PriorityAttribute pattr = new PriorityAttribute(); pattr.Priority = (int)CalculatePriority(110, 30, this.LocalCandidate.component); ///Peer reflexive, not sure of the purpose of this yet //this.Priority; msgRequest.AddAttribute(pattr); IceControllingAttribute cattr = new IceControllingAttribute(); msgRequest.AddAttribute(cattr); UseCandidateAttribute uattr = new UseCandidateAttribute(); msgRequest.AddAttribute(uattr); if (strUsername != null) { UserNameAttribute unameattr = new UserNameAttribute(); unameattr.UserName = strUsername; msgRequest.AddAttribute(unameattr); } /// Add message integrity, computes over all the items currently added /// int nLengthWithoutMessageIntegrity = msgRequest.Bytes.Length; MessageIntegrityAttribute mac = new MessageIntegrityAttribute(); msgRequest.AddAttribute(mac); mac.ComputeHMACShortTermCredentials(msgRequest, nLengthWithoutMessageIntegrity, strPassword); /// Add fingerprint /// int nLengthWithoutFingerPrint = msgRequest.Bytes.Length; FingerPrintAttribute fattr = new FingerPrintAttribute(); msgRequest.AddAttribute(fattr); fattr.ComputeCRC(msgRequest, nLengthWithoutFingerPrint); foreach (int nNextTimeout in Timeouts) { STUNMessage ResponseMessage = stream.SendRecvSTUN(this.RemoteCandidate.IPEndPoint, msgRequest, nNextTimeout); if (ResponseMessage != null) { break; } } }
public void SendIndicationGoogle(RTPStream stream, string strUsername) { /// Google talk appears to send a full stun binding request every 500 ms instead of a binding indication STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; if (strUsername != null) { UserNameAttribute unameattr = new UserNameAttribute(); unameattr.UserName = strUsername; msgRequest.AddAttribute(unameattr); } STUNMessage ResponseMessage = stream.SendRecvSTUN(this.RemoteCandidate.IPEndPoint, msgRequest, 0); }
public void SendIndication(RTPStream stream) { /// Need to send a binding indication every 3 s from now on? STUN2Message msgBindingIndication = new STUN2Message(); msgBindingIndication.Method = StunMethod.Binding; msgBindingIndication.Class = StunClass.Inidication; /// Add fingerprint /// int nLengthWithoutFingerPrint = msgBindingIndication.Bytes.Length; FingerPrintAttribute fattr = new FingerPrintAttribute(); msgBindingIndication.AddAttribute(fattr); fattr.ComputeCRC(msgBindingIndication, nLengthWithoutFingerPrint); stream.SendRecvSTUN(this.RemoteCandidate.IPEndPoint, msgBindingIndication, 0); }
public string CreateAndSendSTUN(DnsEndPoint serverEp) { STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; MappedAddressAttribute mattr = new MappedAddressAttribute(); mattr.IPAddress = LocalEndpoint.Address; mattr.Port = (ushort)LocalEndpoint.Port; msgRequest.AddAttribute(mattr); byte[] tosend = msgRequest.Bytes; return(RTPUDPClient.SendByteArray(tosend, serverEp)); }
void RTPUDPClient_OnReceiveMessage(byte[] bData, int nLength, IPEndPoint epfrom, IPEndPoint epthis, DateTime dtReceived) { /// if we are an performing ICE, see if this is an ICE packet instead of an RTP one if (nLength >= 8) { //0x2112A442 if ((bData[4] == 0x21) && (bData[5] == 0x12) && (bData[6] == 0xA4) && (bData[7] == 0x42)) { /// STUN message STUN2Message smsg = new STUN2Message(); byte[] bStun = new byte[nLength]; Array.Copy(bData, 0, bStun, 0, nLength); smsg.Bytes = bStun; STUNRequestResponse foundreq = null; lock (StunLock) { foreach (STUNRequestResponse queuedreq in StunRequestResponses) { if (queuedreq.IsThisYourResponseSetIfItIs(smsg) == true) { foundreq = queuedreq; break; } } if (foundreq != null) { StunRequestResponses.Remove(foundreq); return; } } if (OnUnhandleSTUNMessage != null) { OnUnhandleSTUNMessage(smsg, epfrom); } return; } } /// TODO... handle RTCP packets if we ever care to }
public void PerformOutgoingSTUNCheckGoogle(RTPStream stream, string strUsername, string strPassword) { STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; if (strUsername != null) { UserNameAttribute unameattr = new UserNameAttribute(); unameattr.UserName = strUsername; msgRequest.AddAttribute(unameattr); } foreach (int nNextTimeout in Timeouts) { STUNMessage ResponseMessage = stream.SendRecvSTUN(this.RemoteCandidate.IPEndPoint, msgRequest, nNextTimeout); ResponseEndpoint = null; if (ResponseMessage != null) { foreach (STUNAttributeContainer cont in ResponseMessage.Attributes) { if (cont.ParsedAttribute.Type == StunAttributeType.MappedAddress) { MappedAddressAttribute attrib = cont.ParsedAttribute as MappedAddressAttribute; ResponseEndpoint = new IPEndPoint(attrib.IPAddress, attrib.Port); } } this.CandidatePairState = RTP.CandidatePairState.Succeeded; break; } else { this.CandidatePairState = RTP.CandidatePairState.Failed; } } }
public STUNMessage SendRecvSTUN1(EndPoint epStun, STUN2Message msgRequest, int nTimeout) { STUNRequestResponse req = new STUNRequestResponse(msgRequest); lock (StunLock) { StunRequestResponses.Add(req); } SendSTUNMessage(msgRequest, epStun); bool bResponse = req.WaitForResponse(nTimeout); lock (StunLock) { if (StunRequestResponses.Contains(req) == true) { StunRequestResponses.Remove(req); } } return(req.ResponseMessage); }
public void PerformOutgoingSTUNCheck(RTPStream stream, string strUsername, string strPassword) { STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; //MappedAddressAttribute mattr = new MappedAddressAttribute(); //mattr.IPAddress = LocalCandidate.IPEndPoint.Address; //mattr.Port = (ushort)LocalCandidate.IPEndPoint.Port; //msgRequest.AddAttribute(mattr); PriorityAttribute pattr = new PriorityAttribute(); pattr.Priority = (int)CalculatePriority(110, 10, this.LocalCandidate.component); ///Peer reflexive, not sure of the purpose of this yet //this.Priority; msgRequest.AddAttribute(pattr); if (IsControlling == true) { IceControllingAttribute cattr = new IceControllingAttribute(); msgRequest.AddAttribute(cattr); } else { IceControlledAttribute cattr = new IceControlledAttribute(); msgRequest.AddAttribute(cattr); } if (strUsername != null) { UserNameAttribute unameattr = new UserNameAttribute(); unameattr.UserName = strUsername; msgRequest.AddAttribute(unameattr); } /// Add message integrity, computes over all the items currently added /// int nLengthWithoutMessageIntegrity = msgRequest.Bytes.Length; MessageIntegrityAttribute mac = new MessageIntegrityAttribute(); msgRequest.AddAttribute(mac); mac.ComputeHMACShortTermCredentials(msgRequest, nLengthWithoutMessageIntegrity, strPassword); /// Add fingerprint /// int nLengthWithoutFingerPrint = msgRequest.Bytes.Length; FingerPrintAttribute fattr = new FingerPrintAttribute(); msgRequest.AddAttribute(fattr); fattr.ComputeCRC(msgRequest, nLengthWithoutFingerPrint); foreach (int nNextTimeout in Timeouts) { STUNMessage ResponseMessage = stream.SendRecvSTUN(this.RemoteCandidate.IPEndPoint, msgRequest, nNextTimeout); ResponseEndpoint = null; if (ResponseMessage != null) { foreach (STUNAttributeContainer cont in ResponseMessage.Attributes) { if (cont.ParsedAttribute.Type == StunAttributeType.MappedAddress) { MappedAddressAttribute attrib = cont.ParsedAttribute as MappedAddressAttribute; ResponseEndpoint = new IPEndPoint(attrib.IPAddress, attrib.Port); } } System.Diagnostics.Debug.WriteLine("STUN check for remote candidate {0} succeeded", this.RemoteCandidate.IPEndPoint); this.CandidatePairState = RTP.CandidatePairState.Succeeded; break; } else { System.Diagnostics.Debug.WriteLine("STUN check for remote candidate {0} failed", this.RemoteCandidate.IPEndPoint); this.CandidatePairState = RTP.CandidatePairState.Failed; } } }
public string CreateAndSendSTUN(DnsEndPoint serverEp) { STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; MappedAddressAttribute mattr = new MappedAddressAttribute(); mattr.IPAddress = LocalEndpoint.Address; mattr.Port = (ushort)LocalEndpoint.Port; msgRequest.AddAttribute(mattr); byte[] tosend = msgRequest.Bytes; return RTPUDPClient.SendByteArray(tosend, serverEp); }
public void TellRemoteEndToUseThisPair(RTPStream stream, string strUsername, string strPassword) { if (IsControlling == false) throw new Exception("Only controlling endpoint can send a usecandidate attribute"); STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; PriorityAttribute pattr = new PriorityAttribute(); pattr.Priority = (int)CalculatePriority(110, 30, this.LocalCandidate.component); ///Peer reflexive, not sure of the purpose of this yet //this.Priority; msgRequest.AddAttribute(pattr); IceControllingAttribute cattr = new IceControllingAttribute(); msgRequest.AddAttribute(cattr); UseCandidateAttribute uattr = new UseCandidateAttribute(); msgRequest.AddAttribute(uattr); if (strUsername != null) { UserNameAttribute unameattr = new UserNameAttribute(); unameattr.UserName = strUsername; msgRequest.AddAttribute(unameattr); } /// Add message integrity, computes over all the items currently added /// int nLengthWithoutMessageIntegrity = msgRequest.Bytes.Length; MessageIntegrityAttribute mac = new MessageIntegrityAttribute(); msgRequest.AddAttribute(mac); mac.ComputeHMACShortTermCredentials(msgRequest, nLengthWithoutMessageIntegrity, strPassword); /// Add fingerprint /// int nLengthWithoutFingerPrint = msgRequest.Bytes.Length; FingerPrintAttribute fattr = new FingerPrintAttribute(); msgRequest.AddAttribute(fattr); fattr.ComputeCRC(msgRequest, nLengthWithoutFingerPrint); foreach (int nNextTimeout in Timeouts) { STUNMessage ResponseMessage = stream.SendRecvSTUN(this.RemoteCandidate.IPEndPoint, msgRequest, nNextTimeout); if (ResponseMessage != null) break; } }
public void PerformOutgoingSTUNCheck(RTPStream stream, string strUsername, string strPassword) { STUN2Message msgRequest = new STUN2Message(); msgRequest.Method = StunMethod.Binding; msgRequest.Class = StunClass.Request; //MappedAddressAttribute mattr = new MappedAddressAttribute(); //mattr.IPAddress = LocalCandidate.IPEndPoint.Address; //mattr.Port = (ushort)LocalCandidate.IPEndPoint.Port; //msgRequest.AddAttribute(mattr); PriorityAttribute pattr = new PriorityAttribute(); pattr.Priority = (int) CalculatePriority(110, 10, this.LocalCandidate.component); ///Peer reflexive, not sure of the purpose of this yet //this.Priority; msgRequest.AddAttribute(pattr); if (IsControlling == true) { IceControllingAttribute cattr = new IceControllingAttribute(); msgRequest.AddAttribute(cattr); } else { IceControlledAttribute cattr = new IceControlledAttribute(); msgRequest.AddAttribute(cattr); } if (strUsername != null) { UserNameAttribute unameattr = new UserNameAttribute(); unameattr.UserName = strUsername; msgRequest.AddAttribute(unameattr); } /// Add message integrity, computes over all the items currently added /// int nLengthWithoutMessageIntegrity = msgRequest.Bytes.Length; MessageIntegrityAttribute mac = new MessageIntegrityAttribute(); msgRequest.AddAttribute(mac); mac.ComputeHMACShortTermCredentials(msgRequest, nLengthWithoutMessageIntegrity, strPassword); /// Add fingerprint /// int nLengthWithoutFingerPrint = msgRequest.Bytes.Length; FingerPrintAttribute fattr = new FingerPrintAttribute(); msgRequest.AddAttribute(fattr); fattr.ComputeCRC(msgRequest, nLengthWithoutFingerPrint); foreach (int nNextTimeout in Timeouts) { STUNMessage ResponseMessage = stream.SendRecvSTUN(this.RemoteCandidate.IPEndPoint, msgRequest, nNextTimeout); ResponseEndpoint = null; if (ResponseMessage != null) { foreach (STUNAttributeContainer cont in ResponseMessage.Attributes) { if (cont.ParsedAttribute.Type == StunAttributeType.MappedAddress) { MappedAddressAttribute attrib = cont.ParsedAttribute as MappedAddressAttribute; ResponseEndpoint = new IPEndPoint(attrib.IPAddress, attrib.Port); } } System.Diagnostics.Debug.WriteLine("STUN check for remote candidate {0} succeeded", this.RemoteCandidate.IPEndPoint); this.CandidatePairState = RTP.CandidatePairState.Succeeded; break; } else { System.Diagnostics.Debug.WriteLine("STUN check for remote candidate {0} failed", this.RemoteCandidate.IPEndPoint); this.CandidatePairState = RTP.CandidatePairState.Failed; } } }
void RTPUDPClient_OnReceiveMessage(byte[] bData, int nLength, IPEndPoint epfrom, IPEndPoint epthis, DateTime dtReceived) { /// if we are an performing ICE, see if this is an ICE packet instead of an RTP one if (nLength >= 8) { //0x2112A442 if ((bData[4] == 0x21) && (bData[5] == 0x12) && (bData[6] == 0xA4) && (bData[7] == 0x42)) { /// STUN message STUNMessage smsg = new STUN2Message(); byte[] bStun = new byte[nLength]; Array.Copy(bData, 0, bStun, 0, nLength); try { smsg.Bytes = bStun; } catch (Exception ex) { smsg = new STUNMessage(); smsg.Bytes = bStun; } STUNRequestResponse foundreq = null; lock (StunLock) { foreach (STUNRequestResponse queuedreq in StunRequestResponses) { if (queuedreq.IsThisYourResponseSetIfItIs(smsg) == true) { foundreq = queuedreq; break; } } if (foundreq != null) { StunRequestResponses.Remove(foundreq); return; } } if (OnUnhandleSTUNMessage != null) { OnUnhandleSTUNMessage(smsg, epfrom); } return; } } RTPPacket packet = RTPPacket.BuildPacket(bData, 0, nLength); if (packet != null) /// Seems we get some TURN channel data messages from google talk { if (ReceiveSSRC == 0) { ReceiveSSRC = packet.SSRC; } if ((packet.PayloadType == this.Payload) && (packet.SSRC == this.ReceiveSSRC)) { IncomingRTPPacketBuffer.AddPacket(packet); } } }