private STUNMessage GetResponse(IPEndPoint receivedEndPoint, STUNMessage stunRequest, bool primary) { if (stunRequest.Header.MessageType == STUNMessageTypesEnum.BindingRequest) { STUNMessage stunResponse = new STUNMessage(); stunResponse.Header.MessageType = STUNMessageTypesEnum.BindingResponse; stunResponse.Header.TransactionId = stunRequest.Header.TransactionId; // Add MappedAddress attribute to indicate the socket the request was received from. STUNAddressAttribute mappedAddressAtt = new STUNAddressAttribute(STUNAttributeTypesEnum.MappedAddress, receivedEndPoint.Port, receivedEndPoint.Address); stunResponse.Attributes.Add(mappedAddressAtt); // Add SourceAddress attribute to indicate the socket used to send the response. if (primary) { STUNAddressAttribute sourceAddressAtt = new STUNAddressAttribute(STUNAttributeTypesEnum.SourceAddress, m_primaryEndPoint.Port, m_primaryEndPoint.Address); stunResponse.Attributes.Add(sourceAddressAtt); } else { STUNAddressAttribute sourceAddressAtt = new STUNAddressAttribute(STUNAttributeTypesEnum.SourceAddress, m_secondaryEndPoint.Port, m_secondaryEndPoint.Address); stunResponse.Attributes.Add(sourceAddressAtt); } // Add ChangedAddress attribute to inidcate the servers alternative socket. if (primary) { STUNAddressAttribute changedAddressAtt = new STUNAddressAttribute(STUNAttributeTypesEnum.ChangedAddress, m_secondaryEndPoint.Port, m_secondaryEndPoint.Address); stunResponse.Attributes.Add(changedAddressAtt); } else { STUNAddressAttribute changedAddressAtt = new STUNAddressAttribute(STUNAttributeTypesEnum.ChangedAddress, m_primaryEndPoint.Port, m_primaryEndPoint.Address); stunResponse.Attributes.Add(changedAddressAtt); } //Console.WriteLine(stunResponse.ToString()); //byte[] stunResponseBuffer = stunResponse.ToByteBuffer(); return(stunResponse); } return(null); }
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); } }