From 3a9ce4a484d22d56d20874f52a60158b9f4d1f29 Mon Sep 17 00:00:00 2001 From: Daniel Salzman <daniel.salzman@nic.cz> Date: Mon, 27 Aug 2012 10:12:18 +0200 Subject: [PATCH] Refactoring 2 --- src/zscanner/NOTES | 16 +++++---- src/zscanner/file_loader.c | 46 ++++++++++++++++---------- src/zscanner/scanner.h | 2 +- src/zscanner/scanner.rl | 63 +++++++++++++++++++++++++----------- src/zscanner/scanner_body.rl | 25 +++++++------- 5 files changed, 95 insertions(+), 57 deletions(-) diff --git a/src/zscanner/NOTES b/src/zscanner/NOTES index 08089fac0d..6195884436 100644 --- a/src/zscanner/NOTES +++ b/src/zscanner/NOTES @@ -1,8 +1,10 @@ +- the new-line character is appended to each zone file before processing (for simplicity) - the class IN is supported only -- time values can have maximal 1 unit (NOT 1D2H) -- \x and \DDD notation is allowed in domain_name and text only -- @ can be used on the right side -- line number in multiline is the number of the last record part -- hex blocks multiple of 2, base64 blocks multiple of 4, base32hex blocks multiple of 8 (DHCID problem) -- RFC 5155 section 3.3 says "unpadded", but padding is used here -- date version of timestamp is limited to the end of the year 2105 due to 32 bits and better check \ No newline at end of file +- time values can have at most 1 time unit (not 1D2H3M) +- \x and \DDD notations are allowed in domain names and text strings only +- upper-case letters are lowered in domain names (including \x and \DDD notations) +- @ can be used instead of domain names anywhere +- the line numbers of multiline records are the numbers of the last lines with appropriate record parts +- items parts lengths must be multiples of 2 for HEX, 4 for base64 and 8 for base32hex blocks (but DHCID example from RFC is more general!) +- NSEC3 hash is with padding (but RFC 5155 section 3.3 says "unpadded") +- date version of timestamp in RRSIG is limited to the end of the year 2105 (for better checking of 32bit integer) \ No newline at end of file diff --git a/src/zscanner/file_loader.c b/src/zscanner/file_loader.c index 2ef0135e9b..c6230b6b70 100644 --- a/src/zscanner/file_loader.c +++ b/src/zscanner/file_loader.c @@ -16,7 +16,7 @@ #include "zscanner/file_loader.h" -#include <stdint.h> +#include <inttypes.h> // PRIu64 #include <unistd.h> #include <stdio.h> #include <stdlib.h> @@ -42,18 +42,24 @@ static int load_settings(file_loader_t *fl) // Temporary scanner for zone settings. settings_scanner = scanner_create(settings_name); + // Use parent processing functions. + settings_scanner->process_record = fl->scanner->process_record; + settings_scanner->process_error = fl->scanner->process_error; + // Scanning zone settings. ret = scanner_process(fl->settings_buffer, fl->settings_buffer + fl->settings_length, - false, + true, settings_scanner); - // Copying scanned settings to actual context. - memcpy(fl->scanner->zone_origin, - settings_scanner->zone_origin, - settings_scanner->zone_origin_length); - fl->scanner->zone_origin_length = settings_scanner->zone_origin_length; - fl->scanner->default_ttl = settings_scanner->default_ttl; + // If no error occured, then copy scanned settings to actual context. + if (ret == 0) { + memcpy(fl->scanner->zone_origin, + settings_scanner->zone_origin, + settings_scanner->zone_origin_length); + fl->scanner->zone_origin_length = settings_scanner->zone_origin_length; + fl->scanner->default_ttl = settings_scanner->default_ttl; + } // Destroying temporary scanner. scanner_free(settings_scanner); @@ -74,6 +80,7 @@ file_loader_t* file_loader_create(const char *file_name, // Creating zeroed structure. file_loader_t *fl = calloc(1, sizeof(file_loader_t)); + if (fl == NULL) { return NULL; } @@ -83,6 +90,7 @@ file_loader_t* file_loader_create(const char *file_name, // Opening zone file. fl->fd = open(fl->file_name, O_RDONLY); + if (fl->fd == -1) { free(fl->file_name); free(fl); @@ -104,11 +112,12 @@ file_loader_t* file_loader_create(const char *file_name, "$ORIGIN %s\n" "$TTL %u\n", zone_origin, default_ttl); + if (ret > 0) { fl->settings_length = ret; } else { - printf("Zone file setttings error!\n"); + printf("Error in zone setttings!\n"); file_loader_free(fl); return NULL; } @@ -134,12 +143,12 @@ int file_loader_process(file_loader_t *fl) long page_size; uint64_t n_blocks, block_id; uint64_t block_size, overlapping_size; - // Start means first valid character; End means first invalid character. + // Start means first valid character; end means first invalid character. uint64_t block_start_position, block_end_position; uint64_t scanner_start_position, scanner_end_position; // For secure termination of zone file. - char *zone_termination = "\n"; + char *zone_termination = "\n"; // Getting OS page size. page_size = sysconf(_SC_PAGESIZE); @@ -156,13 +165,14 @@ int file_loader_process(file_loader_t *fl) // Overlapping size adjustment to multiple of page size. overlapping_size = (BLOCK_OVERLAPPING_SIZE / page_size) * page_size; - // Number of blocks which cover the whole file. + // Number of blocks which cover the whole file (ceiling operation). n_blocks = 1 + ((file_stat.st_size - 1) / block_size); - // Process settings using scanner (like initial ORIGIN). + // Process settings using scanner (like initial ORIGIN and TTL). ret = load_settings(fl); + if (ret != 0) { - printf("Scanner settings processing error!\n"); + printf("Zone defaults error!\n"); return -1; } @@ -195,6 +205,7 @@ int file_loader_process(file_loader_t *fl) MAP_SHARED, fl->fd, block_start_position); + if (data == MAP_FAILED) { printf("Mmap error!\n"); return -1; @@ -206,7 +217,7 @@ int file_loader_process(file_loader_t *fl) return -1; }; - // parser < data, scanner_start_position, scanner_end_position + // Scan zone file. ret = scanner_process(data + scanner_start_position, data + scanner_end_position, false, @@ -220,9 +231,10 @@ int file_loader_process(file_loader_t *fl) fl->scanner); } - // Processing return check. + // Check for error. if (ret != 0) { - printf("Scanner zone file processing error!\n"); + printf("Zone processing has stopped with %"PRIu64" errors!\n", + fl->scanner->error_counter); return -1; } diff --git a/src/zscanner/scanner.h b/src/zscanner/scanner.h index fb2fd5298a..f7e3dc6356 100644 --- a/src/zscanner/scanner.h +++ b/src/zscanner/scanner.h @@ -96,7 +96,7 @@ struct scanner { /*!< Auxiliary buffer length. */ uint32_t buffer_length; - char include_filename[MAX_RDATA_LENGTH]; + char include_filename[MAX_RDATA_LENGTH]; /*!< Bitmap window blocks. */ window windows[BITMAP_WINDOWS]; diff --git a/src/zscanner/scanner.rl b/src/zscanner/scanner.rl index 70717e5e75..3584200cd7 100644 --- a/src/zscanner/scanner.rl +++ b/src/zscanner/scanner.rl @@ -16,19 +16,18 @@ #include "zscanner/scanner.h" -#include <stdint.h> // uint32_t -#include <stdlib.h> // calloc -#include <stdio.h> // sprintf -#include <limits.h> // PATH_MAX -#include <libgen.h> // dirname -#include <stdbool.h> // bool -#include <sys/socket.h> // AF_INET (BSD) -#include <netinet/in.h> // in_addr (BSD) - -#include "util/error.h" // error codes -#include "util/descriptor.h" // KNOT_RRTYPE_A -#include "zscanner/file_loader.h" // include processing -#include "zscanner/scanner_functions.h" +#include <stdint.h> // uint32_t +#include <stdlib.h> // calloc +#include <stdio.h> // sprintf +#include <libgen.h> // dirname +#include <stdbool.h> // bool +#include <sys/socket.h> // AF_INET (BSD) +#include <netinet/in.h> // in_addr (BSD) + +#include "util/error.h" // error codes +#include "util/descriptor.h" // KNOT_RRTYPE_A +#include "zscanner/file_loader.h" // file_loader +#include "zscanner/scanner_functions.h" // Base64 #define SCANNER_WARNING(code) { s->error_code = code; } #define SCANNER_ERROR(code) { s->error_code = code; s->stop = true; } @@ -91,7 +90,6 @@ int scanner_process(char *start, { // Necessary scanner variables. int stack[RAGEL_STACK_SIZE]; - int ret = 0; char *ts = NULL, *eof = NULL; char *p = start, *pe = end; @@ -101,6 +99,7 @@ int scanner_process(char *start, uint8_t win, byte_pos, bit_pos; uint32_t timestamp; int16_t window; + int ret; // Next 2 variables are for better performance. // Restoring r_data pointer to next free space. @@ -126,18 +125,46 @@ int scanner_process(char *start, // Writing scanner body (in C). %% write exec; - // Scanner error state check. + // Check if scanner state machine is in uncovered state. if (cs == zone_scanner_error) { - printf("Unknown scanner error!\n"); + SCANNER_ERROR(ZSCANNER_UNCOVERED_STATE); + s->error_counter++; + + // Fill error context data. + for (s->buffer_length = 0; + ((p + s->buffer_length) < pe) && + (s->buffer_length < sizeof(s->buffer) - 1); + s->buffer_length++) + { + // Only rest of the current line. + if (*(p + s->buffer_length) == '\n') { + break; + } + s->buffer[s->buffer_length] = *(p + s->buffer_length); + } + + // Ending string in buffer. + s->buffer[s->buffer_length++] = 0; + + // Processing error. + s->process_error(s); + + return -1; + } + + // Check if any errors occured. + if (s->error_counter > 0) { return -1; } // Storing scanner states. s->cs = cs; s->top = top; - s->r_data_tail = rdata_tail - s->r_data; memcpy(s->stack, stack, sizeof(stack)); + // Storing r_data pointer + s->r_data_tail = rdata_tail - s->r_data; + // Storing unprocessed token shift if (ts != NULL) { s->token_shift = pe - ts; @@ -146,6 +173,6 @@ int scanner_process(char *start, s->token_shift = 0; } - return ret; + return 0; } diff --git a/src/zscanner/scanner_body.rl b/src/zscanner/scanner_body.rl index b7d07c75ce..f3280d984b 100644 --- a/src/zscanner/scanner_body.rl +++ b/src/zscanner/scanner_body.rl @@ -198,8 +198,8 @@ s->dname_tmp_length = 0; } action _dname_error { - SCANNER_WARNING(ZSCANNER_EBAD_DNAME_CHAR); - fhold; fgoto err_line; + SCANNER_WARNING(ZSCANNER_EBAD_DNAME_CHAR); + fhold; fgoto err_line; } relative_dname = (labels ) >_dname_init %_relative_dname_exit; @@ -483,7 +483,7 @@ text_array = (text_with_length . (sep . text_with_length)*) %_item_exit; # END - # BEGIN - TTL directives processing + # BEGIN - TTL directive processing action _default_ttl_exit { if (s->number64 <= UINT32_MAX) { s->default_ttl = (uint32_t)(s->number64); @@ -506,7 +506,7 @@ } # END - # BEGIN - ORIGIN directives processing + # BEGIN - ORIGIN directive processing action _zone_origin_init { s->dname = s->zone_origin; } @@ -526,7 +526,7 @@ } # END - # BEGIN - INCLUDE directives processing + # BEGIN - INCLUDE directive processing action _incl_filename_init { rdata_tail = s->r_data; } @@ -962,7 +962,6 @@ | "KX"i %{ TYPE_NUM(KNOT_RRTYPE_KX); } | "CERT"i %{ TYPE_NUM(KNOT_RRTYPE_CERT); } | "DNAME"i %{ TYPE_NUM(KNOT_RRTYPE_DNAME); } - | "OPT"i %{ TYPE_NUM(KNOT_RRTYPE_OPT); } | "APL"i %{ TYPE_NUM(KNOT_RRTYPE_APL); } | "DS"i %{ TYPE_NUM(KNOT_RRTYPE_DS); } | "SSHFP"i %{ TYPE_NUM(KNOT_RRTYPE_SSHFP); } @@ -1020,7 +1019,6 @@ | "KX"i %{ WINDOW_ADD_BIT(KNOT_RRTYPE_KX); } | "CERT"i %{ WINDOW_ADD_BIT(KNOT_RRTYPE_CERT); } | "DNAME"i %{ WINDOW_ADD_BIT(KNOT_RRTYPE_DNAME); } - | "OPT"i %{ WINDOW_ADD_BIT(KNOT_RRTYPE_OPT); } | "APL"i %{ WINDOW_ADD_BIT(KNOT_RRTYPE_APL); } | "DS"i %{ WINDOW_ADD_BIT(KNOT_RRTYPE_DS); } | "SSHFP"i %{ WINDOW_ADD_BIT(KNOT_RRTYPE_SSHFP); } @@ -1093,14 +1091,14 @@ action _fc_write { *rdata_tail = digit_to_num[(uint8_t)fc]; rdata_tail++; - ADD_R_DATA_LABEL } - gateway = ( ('0' $_fc_write . sep . number8 . sep . '.') - | ('1' $_fc_write . sep . number8 . sep . ipv4_address) - | ('2' $_fc_write . sep . number8 . sep . ipv6_address) - | ('3' $_fc_write . sep . number8 . sep . r_dname) - ); + gateway = + ( ('0' $_fc_write %_item_exit . sep . number8 . sep . '.') + | ('1' $_fc_write %_item_exit . sep . number8 . sep . ipv4_address) + | ('2' $_fc_write %_item_exit . sep . number8 . sep . ipv6_address) + | ('3' $_fc_write %_item_exit . sep . number8 . sep . r_dname) + ); # END # BEGIN - Auxiliary functions which call smaller state machines @@ -1360,7 +1358,6 @@ | "KX"i %_data_ | "CERT"i %_data_ | "DNAME"i %_data_dname - | "OPT"i %_data_ | "APL"i %_data_ | "DS"i %_data_ds | "SSHFP"i %_data_sshfp -- GitLab