public static List <STUNAttribute> ParseMessageAttributes(byte[] buffer, int startIndex, int endIndex) { if (buffer != null && buffer.Length > startIndex && buffer.Length >= endIndex) { List <STUNAttribute> attributes = new List <STUNAttribute>(); int startAttIndex = startIndex; while (startAttIndex < endIndex) { UInt16 stunAttributeType = BitConverter.ToUInt16(buffer, startAttIndex); UInt16 stunAttributeLength = BitConverter.ToUInt16(buffer, startAttIndex + 2); byte[] stunAttributeValue = null; if (BitConverter.IsLittleEndian) { stunAttributeType = Utility.ReverseEndian(stunAttributeType); stunAttributeLength = Utility.ReverseEndian(stunAttributeLength); } if (stunAttributeLength > 0) { if (stunAttributeType == (int)STUNAttributeTypesEnum.Username && stunAttributeLength > buffer.Length - startIndex - 4) { // Received some STUN messages where the username is shorter than the claimed length. int realLength = buffer.Length - startIndex - 4; stunAttributeValue = new byte[realLength]; Buffer.BlockCopy(buffer, startIndex + 4, stunAttributeValue, 0, realLength); } else { stunAttributeValue = new byte[stunAttributeLength]; Buffer.BlockCopy(buffer, startIndex + 4, stunAttributeValue, 0, stunAttributeLength); } } STUNAttributeTypesEnum attributeType = STUNAttributeTypes.GetSTUNAttributeTypeForId(stunAttributeType); STUNAttribute attribute = null; if (attributeType == STUNAttributeTypesEnum.ChangeRequest) { attribute = new STUNChangeRequestAttribute(stunAttributeValue); } else if (attributeType == STUNAttributeTypesEnum.MappedAddress) { attribute = new STUNAddressAttribute(stunAttributeValue); } else { attribute = new STUNAttribute(attributeType, stunAttributeLength, stunAttributeValue); } attributes.Add(attribute); startAttIndex = startAttIndex + 4 + stunAttributeLength; } return(attributes); } else { return(null); } }
public void STUNPrimaryReceived(IPEndPoint localEndPoint, IPEndPoint receivedEndPoint, byte[] buffer, int bufferLength) { try { //Console.WriteLine("\n=> received from " + IPSocketAddress.GetSocketString(receivedEndPoint) + " on " + IPSocketAddress.GetSocketString(receivedOnEndPoint)); //Console.WriteLine(Utility.PrintBuffer(buffer)); STUNMessage stunRequest = STUNMessage.ParseSTUNMessage(buffer, bufferLength); //Console.WriteLine(stunRequest.ToString()); FireSTUNPrimaryRequestInTraceEvent(localEndPoint, receivedEndPoint, stunRequest); STUNMessage stunResponse = GetResponse(receivedEndPoint, stunRequest, true); byte[] stunResponseBuffer = stunResponse.ToByteBuffer(); bool changeAddress = false; bool changePort = false; foreach (STUNAttribute attr in stunRequest.Attributes) { if (attr.AttributeType == STUNAttributeTypesEnum.ChangeRequest) { STUNChangeRequestAttribute changeReqAttr = (STUNChangeRequestAttribute)attr; changeAddress = changeReqAttr.ChangeAddress; changePort = changeReqAttr.ChangePort; break; } } if (!changeAddress) { if (!changePort) { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_primaryEndPoint)); m_primarySend(receivedEndPoint, stunResponseBuffer); FireSTUNPrimaryResponseOutTraceEvent(m_primaryEndPoint, receivedEndPoint, stunResponse); } else { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_primaryDiffPortEndPoint)); m_primaryDiffPortSocket.Send(stunResponseBuffer, stunResponseBuffer.Length, receivedEndPoint); FireSTUNPrimaryResponseOutTraceEvent(m_primaryDiffPortEndPoint, receivedEndPoint, stunResponse); } } else { if (!changePort) { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_secondaryEndPoint)); m_secondarySend(receivedEndPoint, stunResponseBuffer); FireSTUNSecondaryResponseOutTraceEvent(m_secondaryEndPoint, receivedEndPoint, stunResponse); } else { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_secondaryDiffPortEndPoint)); m_secondaryDiffPortSocket.Send(stunResponseBuffer, stunResponseBuffer.Length, receivedEndPoint); FireSTUNSecondaryResponseOutTraceEvent(m_secondaryDiffPortEndPoint, receivedEndPoint, stunResponse); } } } catch (Exception excp) { logger.Debug("Exception STUNPrimaryReceived. " + excp.Message); } }