Commit 87428391 authored by Lubos Slovak's avatar Lubos Slovak

Parsing rest of packet in processing functions

- Added packet_parse_rest() to parse the rest of the packet from
  wireformat.
- Modified ns_parse_packet() to parse only the Question section.
- Modified ns_answer_normal() to parse rest of the packet.
- ns_answer_axfr() does not need any other parsing (we may ommit
  the OPT RR).
- Modified axfrin_transfer_needed() to parse rest of the packet.

refs #800 @1h
parent b020644a
......@@ -665,6 +665,49 @@ int dnslib_packet_parse_from_wire(dnslib_packet_t *packet,
/*----------------------------------------------------------------------------*/
int dnslib_packet_parse_rest(dnslib_packet_t *packet)
{
if (packet->parsed >= packet->size) {
return DNSLIB_EOK;
}
size_t pos = packet->parsed;
int err;
debug_dnslib_packet("Parsing Answer RRs...\n");
if ((err = dnslib_packet_parse_rrs(packet->wireformat, &pos,
packet->size, packet->header.ancount, &packet->answer,
&packet->an_rrsets, &packet->max_an_rrsets, packet)) != DNSLIB_EOK) {
return err;
}
debug_dnslib_packet("Parsing Authority RRs...\n");
if ((err = dnslib_packet_parse_rrs(packet->wireformat, &pos,
packet->size, packet->header.nscount, &packet->authority,
&packet->ns_rrsets, &packet->max_ns_rrsets, packet)) != DNSLIB_EOK) {
return err;
}
debug_dnslib_packet("Parsing Additional RRs...\n");
if ((err = dnslib_packet_parse_rrs(packet->wireformat, &pos,
packet->size, packet->header.arcount, &packet->additional,
&packet->ar_rrsets, &packet->max_ar_rrsets, packet)) != DNSLIB_EOK) {
return err;
}
if (pos < packet->size) {
// some trailing garbage; ignore, but log
debug_dnslib_response("Packet: %zu bytes of trailing garbage "
"in packet.\n", pos - packet->size);
}
packet->parsed = packet->size;
return DNSLIB_EOK;
}
/*----------------------------------------------------------------------------*/
int dnslib_packet_set_max_size(dnslib_packet_t *packet, int max_size)
{
if (packet == NULL || max_size <= 0) {
......
......@@ -252,6 +252,8 @@ int dnslib_packet_parse_from_wire(dnslib_packet_t *packet,
const uint8_t *wireformat, size_t size,
int question_only);
int dnslib_packet_parse_rest(dnslib_packet_t *packet);
/*!
* \brief Sets the maximum size of the packet and allocates space for wire
* format (if needed).
......
#include <assert.h>
#include "knot/server/axfr-in.h"
#include "knot/common.h"
......@@ -96,8 +98,21 @@ int axfrin_create_soa_query(const dnslib_dname_t *zone_name, uint8_t *buffer,
/*----------------------------------------------------------------------------*/
int axfrin_transfer_needed(const dnslib_zone_t *zone,
const dnslib_packet_t *soa_response)
dnslib_packet_t *soa_response)
{
// first, parse the rest of the packet
assert(!dnslib_packet_is_query(soa_response));
debug_ns("Response - parsed: %zu, total wire size: %zu\n",
soa_response->parsed, soa_response->size);
int ret;
if (soa_response->parsed < soa_response->size) {
ret = dnslib_packet_parse_rest(soa_response);
if (ret != DNSLIB_EOK) {
return ret;
}
}
/*
* Retrieve the local Serial
*/
......
......@@ -23,7 +23,7 @@ int axfrin_create_soa_query(const dnslib_dname_t *zone_name, uint8_t *buffer,
size_t *size);
int axfrin_transfer_needed(const dnslib_zone_t *zone,
const dnslib_packet_t *soa_response);
dnslib_packet_t *soa_response);
int axfrin_create_axfr_query(const dnslib_dname_t *zone_name, uint8_t *buffer,
size_t *size);
......
......@@ -2158,35 +2158,14 @@ int ns_parse_packet(const uint8_t *query_wire, size_t qsize,
int ret = 0;
// 2) parse the query
// if ((ret = dnslib_response_parse_query(parsed, query_wire,
// qsize)) != 0) {
// log_answer_info("Error while parsing packet, "
// "dnslib error '%s'.\n", dnslib_strerror(ret));
// //dnslib_response_free(&parsed);
// return DNSLIB_RCODE_FORMERR;
// }
// parse the query to the new structure
// dnslib_packet_t *packet = dnslib_packet_new(DNSLIB_PACKET_PREALLOC_NONE);
// if (packet == NULL) {
// log_answer_info("Error while creating packet structure.");
// dnslib_response_free(&parsed);
// return DNSLIB_RCODE_SERVFAIL;
// }
if ((ret = dnslib_packet_parse_from_wire(packet, query_wire,
qsize, 0)) != 0) {
qsize, 1)) != 0) {
log_answer_info("Error while parsing packet, "
"dnslib error '%s'.\n", dnslib_strerror(ret));
// dnslib_response_free(&parsed);
return DNSLIB_RCODE_FORMERR;
}
// debug_ns("Packet parsed.\n");
//dnslib_response_dump(parsed);
// debug_ns("Done\n");
// 3) determine the query type
switch (dnslib_packet_opcode(packet)) {
case DNSLIB_OPCODE_QUERY:
......@@ -2320,6 +2299,19 @@ void ns_error_response(ns_nameserver_t *nameserver, uint16_t query_id,
int ns_answer_normal(ns_nameserver_t *nameserver, dnslib_packet_t *query,
uint8_t *response_wire, size_t *rsize)
{
// first, parse the rest of the packet
assert(dnslib_packet_is_query(query));
debug_ns("Query - parsed: %zu, total wire size: %zu\n", query->parsed,
query->size);
int ret;
if (query->parsed < query->size) {
ret = dnslib_packet_parse_rest(query);
if (ret != DNSLIB_EOK) {
return ret;
}
}
// get the answer for the query
rcu_read_lock();
dnslib_zonedb_t *zonedb = rcu_dereference(nameserver->zone_db);
......@@ -2337,7 +2329,7 @@ int ns_answer_normal(ns_nameserver_t *nameserver, dnslib_packet_t *query,
return KNOT_EOK;
}
int ret = dnslib_packet_set_max_size(response, *rsize);
ret = dnslib_packet_set_max_size(response, *rsize);
if (ret != DNSLIB_EOK) {
log_server_warning("Failed to init response structure.\n");
......@@ -2402,6 +2394,8 @@ int ns_answer_axfr(ns_nameserver_t *nameserver, ns_xfr_t *xfr)
return KNOT_EINVAL;
}
// no need to parse rest of the packet
// initialize response packet structure
dnslib_packet_t *response = dnslib_packet_new(
DNSLIB_PACKET_PREALLOC_RESPONSE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment