function Query($question, $type = "A")
 {
     $this->ClearError();
     $typeid = $this->types->GetByName($type);
     if ($typeid === false) {
         $this->SetError("Invalid Query Type " . $type);
         return false;
     }
     if ($this->udp) {
         $host = "udp://" . $this->server;
     } else {
         $host = $this->server;
     }
     if (!($socket = fsockopen($host, $this->port, $this->timeout))) {
         $this->SetError("Failed to Open Socket");
         return false;
     }
     // Split Into Labels
     if (preg_match("/[a-z|A-Z]/", $question) == 0) {
         $labeltmp = explode(".", $question);
         // reverse ARPA format
         for ($i = count($labeltmp) - 1; $i >= 0; $i--) {
             $labels[] = $labeltmp[$i];
         }
         $labels[] = "IN-ADDR";
         $labels[] = "ARPA";
     } else {
         // hostname
         $labels = explode(".", $question);
     }
     $question_binary = "";
     for ($a = 0; $a < count($labels); $a++) {
         $size = strlen($labels[$a]);
         $question_binary .= pack("C", $size);
         // size byte first
         $question_binary .= $labels[$a];
         // then the label
     }
     $question_binary .= pack("C", 0);
     // end it off
     $this->Debug("Question: " . $question . " (type=" . $type . "/" . $typeid . ")");
     $id = rand(1, 255) | rand(0, 255) << 8;
     // generate the ID
     // Set standard codes and flags
     $flags = 0x100 & 0x300;
     // recursion & queryspecmask
     $opcode = 0x0;
     // opcode
     // Build the header
     $header = "";
     $header .= pack("n", $id);
     $header .= pack("n", $opcode | $flags);
     $header .= pack("nnnn", 1, 0, 0, 0);
     $header .= $question_binary;
     $header .= pack("n", $typeid);
     $header .= pack("n", 0x1);
     // internet class
     $headersize = strlen($header);
     $headersizebin = pack("n", $headersize);
     $this->Debug("Header Length: " . $headersize . " Bytes");
     $this->DebugBinary($header);
     if ($this->udp && $headersize >= 512) {
         $this->SetError("Question too big for UDP (" . $headersize . " bytes)");
         fclose($socket);
         return false;
     }
     if ($this->udp) {
         if (!fwrite($socket, $header, $headersize)) {
             $this->SetError("Failed to write question to socket");
             fclose($socket);
             return false;
         }
         if (!($this->rawbuffer = fread($socket, 4096))) {
             $this->SetError("Failed to write read data buffer");
             fclose($socket);
             return false;
         }
     } else {
         if (!fwrite($socket, $headersizebin)) {
             $this->SetError("Failed to write question length to TCP socket");
             fclose($socket);
             return false;
         }
         if (!fwrite($socket, $header, $headersize)) {
             $this->SetError("Failed to write question to TCP socket");
             fclose($socket);
             return false;
         }
         if (!($returnsize = fread($socket, 2))) {
             $this->SetError("Failed to read size from TCP socket");
             fclose($socket);
             return false;
         }
         $tmplen = unpack("nlength", $returnsize);
         $datasize = $tmplen['length'];
         $this->Debug("TCP Stream Length Limit " . $datasize);
         if (!($this->rawbuffer = fread($socket, $datasize))) {
             $this->SetError("Failed to read data buffer");
             fclose($socket);
             return false;
         }
     }
     fclose($socket);
     $buffersize = strlen($this->rawbuffer);
     $this->Debug("Read Buffer Size " . $buffersize);
     if ($buffersize < 12) {
         $this->SetError("Return Buffer too Small");
         return false;
     }
     $this->rawheader = substr($this->rawbuffer, 0, 12);
     // first 12 bytes is the header
     $this->rawresponse = substr($this->rawbuffer, 12);
     // after that the response
     $this->responsecounter = 12;
     // start parsing response counter from 12 - no longer using response so can do pointers
     $this->DebugBinary($this->rawbuffer);
     $this->header = unpack("nid/nspec/nqdcount/nancount/nnscount/narcount", $this->rawheader);
     $answers = $this->header['ancount'];
     $this->Debug("Query Returned " . $answers . " Answers");
     $dns_answer = new DNSAnswer();
     // Deal with the header question data
     if ($this->header['qdcount'] > 0) {
         $this->Debug("Found " . $this->header['qdcount'] . " Questions");
         for ($a = 0; $a < $this->header['qdcount']; $a++) {
             $c = 1;
             while ($c != 0) {
                 $c = hexdec(bin2hex($this->ReadResponse(1)));
             }
             $extradata = $this->ReadResponse(4);
         }
     }
     // New Functional Method
     for ($a = 0; $a < $this->header['ancount']; $a++) {
         $record = $this->ReadRecord();
         $dns_answer->AddResult($record['header']['type'], $record['typeid'], $record['header']['class'], $record['header']['ttl'], $record['data'], $record['domain'], $record['string'], $record['extras']);
     }
     $this->lastnameservers = new DNSAnswer();
     for ($a = 0; $a < $this->header['nscount']; $a++) {
         $record = $this->ReadRecord();
         $this->lastnameservers->AddResult($record['header']['type'], $record['typeid'], $record['header']['class'], $record['header']['ttl'], $record['data'], $record['domain'], $record['string'], $record['extras']);
     }
     $this->lastadditional = new DNSAnswer();
     for ($a = 0; $a < $this->header['arcount']; $a++) {
         $record = $this->ReadRecord();
         $this->lastadditional->AddResult($record['header']['type'], $record['typeid'], $record['header']['class'], $record['header']['ttl'], $record['data'], $record['domain'], $record['string'], $record['extras']);
     }
     return $dns_answer;
 }