void DNSServer::onReceive(pbuf* buf, IPAddress remoteIP, uint16_t remotePort)
{


    if (_buffer != NULL) free(_buffer);
    _buffer = (char*)malloc(buf->tot_len * sizeof(char));
    if (_buffer == NULL) return;
    pbuf_copy_partial(buf, _buffer, buf->tot_len, 0);
    debugf("DNS REQ for %s from %s:%d", getDomainNameWithoutWwwPrefix().c_str(), remoteIP.toString().c_str(), remotePort);
    _dnsHeader = (DNSHeader*) _buffer;
	if (_dnsHeader->QR == DNS_QR_QUERY &&
	        _dnsHeader->OPCode == DNS_OPCODE_QUERY &&
	        requestIncludesOnlyOneQuestion() &&
	        (_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName)
	       )
		{
			char response[buf->tot_len+16];
			int idx = buf->tot_len;
			_dnsHeader->QR = DNS_QR_RESPONSE;
			_dnsHeader->ANCount = _dnsHeader->QDCount;
			_dnsHeader->QDCount = _dnsHeader->QDCount;
			memcpy(response, _buffer, idx);
			//Set a pointer to the domain name in the question section
			response[idx] = 0xC0;
			response[idx+1] = 0x0C;

			//Type: "Host Address"
			response[idx+2] = 0x00;
			response[idx+3] = 0x01;

			//Set the response class to IN
			response[idx+4] = 0x00;
			response[idx+5] = 0x01;

			//TTL
			response[idx+6] = _ttl >> 24;
			response[idx+7] = _ttl >> 16;
			response[idx+8] = _ttl >> 8;
			response[idx+9] = _ttl;

			//RDATA length
			response[idx+10] = 0x00;
			response[idx+11] = 0x04; //4 byte IP address

			//The IP address
			response[idx+12] = _resolvedIP[0];
			response[idx+13] = _resolvedIP[1];
			response[idx+14] = _resolvedIP[2];
			response[idx+15] = _resolvedIP[3];

			sendTo(remoteIP, remotePort, response, idx+16);
	    }
void DNSServer::processNextRequest()
{
  _currentPacketSize = _udp.parsePacket();
  if (_currentPacketSize)
  {
    _buffer = (unsigned char*)malloc(_currentPacketSize * sizeof(char));
    _udp.read(_buffer, _currentPacketSize);
    _dnsHeader = (DNSHeader*) _buffer;

    if (_dnsHeader->QR == DNS_QR_QUERY &&
        _dnsHeader->OPCode == DNS_OPCODE_QUERY &&
        requestIncludesOnlyOneQuestion() &&
        (_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName)
       )
    {
      replyWithIP();
    }
    else if (_dnsHeader->QR == DNS_QR_QUERY)
    {
      replyWithCustomCode();
    }

    free(_buffer);
  }
}
void DNSServer::replyWithIP()
{
  _dnsHeader->QR = DNS_QR_RESPONSE;
  _dnsHeader->ANCount = _dnsHeader->QDCount;
  _dnsHeader->QDCount = _dnsHeader->QDCount; 
  //_dnsHeader->RA = 1;  

  _udp.beginPacket(_udp.remoteIP(), _udp.remotePort());
  _udp.write(_buffer, _currentPacketSize);

  _udp.write((uint8_t)192); //  answer name is a pointer
  _udp.write((uint8_t)12);  // pointer to offset at 0x00c

  _udp.write((uint8_t)0);   // 0x0001  answer is type A query (host address)
  _udp.write((uint8_t)1);

  _udp.write((uint8_t)0);   //0x0001 answer is class IN (internet address)
  _udp.write((uint8_t)1);
 
  _udp.write((unsigned char*)&_ttl, 4);

  // Length of RData is 4 bytes (because, in this case, RData is IPv4)
  _udp.write((uint8_t)0);
  _udp.write((uint8_t)4);
  _udp.write(_resolvedIP, sizeof(_resolvedIP));
  _udp.endPacket();



  #ifdef DEBUG
    DEBUG_OUTPUT.print("DNS responds: ");
    DEBUG_OUTPUT.print(_resolvedIP[0]);
    DEBUG_OUTPUT.print(".");
    DEBUG_OUTPUT.print(_resolvedIP[1]);
    DEBUG_OUTPUT.print(".");
    DEBUG_OUTPUT.print(_resolvedIP[2]);
    DEBUG_OUTPUT.print(".");
    DEBUG_OUTPUT.print(_resolvedIP[3]);
    DEBUG_OUTPUT.print(" for ");
    DEBUG_OUTPUT.println(getDomainNameWithoutWwwPrefix());
  #endif
}