// tries to parse the specified chunk of bytes as a multicast policy packet.  If it can,
        // it returns a managed representation.  Otherwise, it returns null.
        public static MulticastPolicyPacket Parse(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0 || offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if (count < 0 || count > (buffer.Length - offset))
            {
                throw new ArgumentOutOfRangeException("count");
            }

            if (count < ConstantLength)
            {
                // malformed packet - not long enough even if both variable-length fields are empty
                return null;
            }

            if (buffer[offset] != HeaderBytes[0] ||
                buffer[offset + 1] != HeaderBytes[1] ||
                buffer[offset + 2] != HeaderBytes[2])
            {
                // malformed packet - doesn't have the header
                return null;
            }

            if (buffer[offset + 3] != 1)
            {
                // we only understand version 1 of the protocol - ignore anything using a newer version.
                return null;
            }

            MulticastPolicyPacket rval = new MulticastPolicyPacket();

            rval.type = (MulticastPolicyPacketType)buffer[offset + 4];

            rval.messageId[0] = buffer[offset + 5];
            rval.messageId[1] = buffer[offset + 6];
            rval.messageId[2] = buffer[offset + 7];
            rval.messageId[3] = buffer[offset + 8];

            rval.port = ((int)buffer[offset + 9]) | (((int)buffer[offset + 10]) << 8);

            int applicationOriginLength = (buffer[offset + 11]) | (buffer[offset + 12] << 8);
            int groupAddressLength = buffer[offset + 13];

            offset += 14;

            if ((offset + applicationOriginLength) > count)
            {
                // malformed packet - application origin length past the end of the buffer
                return null;
            }

            rval.applicationOriginBytes = new byte[applicationOriginLength];
            Buffer.BlockCopy(buffer, offset, rval.applicationOriginBytes, 0, applicationOriginLength);

            try
            {
                UTF8Encoding encoding = new UTF8Encoding(false, true);
                rval.applicationOrigin = encoding.GetString(rval.applicationOriginBytes, 0, applicationOriginLength);
            }
            catch (DecoderFallbackException)
            {
                // malformed packet - invalid UTF8 in application origin uri
                return null;
            }

            offset += applicationOriginLength;

            if ((offset + groupAddressLength) > count)
            {
                // malformed packet - group address length past the end of the buffer
                return null;
            }

            if (groupAddressLength != 4 && groupAddressLength != 16)
            {
                // malformed packet - group address isn't ipv4 or ipv6
                return null;
            }

            rval.groupAddressBytes = new byte[groupAddressLength];
            Buffer.BlockCopy(buffer, offset, rval.groupAddressBytes, 0, groupAddressLength);
            rval.groupAddress = new IPAddress(rval.groupAddressBytes);

            return rval;
        }
        private bool ProcessSingleSourceAnnouncement(MulticastPolicyPacket packet, EndPoint source)
        {
            bool async = false;

            Trace.TraceInformation("MulticastPolicyServerCore<" + addressFamily + ">: " +
                "Processing packet with GroupAddress=" + packet.GroupAddress + ", Port=" + packet.Port +
                ", ApplicationOrigin=" + packet.ApplicationOrigin);

            if (ShouldRespondToPacket(packet, configuration.InternalSingleSourceConfiguration))
            {
                packet.Type = MulticastPolicyPacketType.Authorization;

                int packetLength = packet.SerializeTo(buffer, 0, buffer.Length);

                IAsyncResult result;

                try
                {
                    result = socket.BeginSendTo(buffer, 0, packetLength, SocketFlags.None, source, SendCompletionCallback, null);
                }
                catch (SocketException ex)
                {
                    Trace.TraceWarning("MulticastPolicyServerCore<{0}>: Error while sending authorization packet: {1}",
                        addressFamily, ex);
                    return false;
                }

                async = !(result.CompletedSynchronously);

                if (!async)
                {
                    ProcessSendCompletion(result, false);
                }
            }

            return async;
        }
        private bool ShouldRespondToPacket(MulticastPolicyPacket packet, PrefixKeyedDictionary<MulticastResource> config)
        {
            ICollection<MulticastResource> allowedResources = null;
            if (!config.TryGetValueByPrefixMatch(packet.ApplicationOrigin, out allowedResources))
            {
                Trace.TraceInformation(
                    "MulticastPolicyServerCore<{0}>: Rejecting because the app is blocked entirely",
                    addressFamily);
                return false;
            }

            foreach (MulticastResource resource in allowedResources)
            {
                if ((resource.GroupAddress == IPAddress.Any ||
                     IPAddress.Equals(resource.GroupAddress, packet.GroupAddress)) &&
                    (resource.HighPort >= packet.Port && resource.LowPort <= packet.Port))
                {
                    Trace.TraceInformation(
                        "MulticastPolicyServerCore<{0}>: Access is allowed, sending authorization packet",
                        addressFamily);
                    return true;
                }
            }

            Trace.TraceInformation(
                "MulticastPolicyServerCore<{0}>: Rejecting because the app is requesting access to an unapproved group/port",
                addressFamily);
            return false;
        }
        private bool ProcessPacket(MulticastPolicyPacket packet, EndPoint source, IPPacketInformation packetInfo)
        {
            if (packet == null)
            {
                return false;
            }

            if (packet.Type != MulticastPolicyPacketType.Announcement)
            {
                return false;
            }

            bool async;

            if (IsMulticastAddress(packetInfo.Address))
            {
                async = ProcessAnySourceAnnouncement(packet, packetInfo);
            }
            else
            {
                async = ProcessSingleSourceAnnouncement(packet, source);
            }

            return async;
        }