mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 17:38:59 +00:00
FS-3110 --comment-only phase 1 to replace udns with ldns in mod_enum may need to rerun bootstrap
This commit is contained in:
272
libs/ldns/examples/ldns-zsplit.c
Normal file
272
libs/ldns/examples/ldns-zsplit.c
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* read a zone from disk and split it up:
|
||||
*
|
||||
* zone: SOA a b c d e f g h i j k l
|
||||
* becomes:
|
||||
* zone1: SOA a b c d e f
|
||||
* zone2: SOA f g h i k l
|
||||
*
|
||||
* ldns-catzone removes the last name and put
|
||||
* the zone back together.
|
||||
*
|
||||
* This way you can incremental sign a zone
|
||||
*
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <errno.h>
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
#define DEFAULT_SPLIT 1000
|
||||
#define FILE_SIZE 255
|
||||
#define SPLIT_MAX 999
|
||||
#define NO_SPLIT 0
|
||||
#define INTENT_TO_SPLIT 1
|
||||
#define SPLIT_NOW 2
|
||||
|
||||
static void
|
||||
usage(FILE *f, char *progname)
|
||||
{
|
||||
fprintf(f, "Usage: %s [OPTIONS] <zonefile> [keys]\n", progname);
|
||||
fprintf(f, " Cut a zone file into pieces, each part is put in a file\n");
|
||||
fprintf(f, " named: '<zonefile>.NNN'. Where NNN is a integer ranging 000 to 999.\n");
|
||||
fprintf(f, " If key files are given they are inserted in each part.\n");
|
||||
fprintf(f, " The original SOA is also included in each part, making them correct DNS\n");
|
||||
fprintf(f, " (mini) zones.\n");
|
||||
fprintf(f, " This utility can be used to parallel sign a large zone.\n");
|
||||
fprintf(f, " To make it work the original zone needs to be canonical ordered.\n");
|
||||
fprintf(f, "\nOPTIONS:\n");
|
||||
fprintf(f, " -n NUMBER\tsplit after this many RRs\n");
|
||||
fprintf(f, " -o ORIGIN\tuse this as initial origin, for zones starting with @\n");
|
||||
fprintf(f, " -z\t\tsort the zone prior to splitting. The current ldns zone\n");
|
||||
fprintf(f, " \t\timplementation makes this unuseable for large zones.\n");
|
||||
fprintf(f, " -v\t\tshow version number and exit\n");
|
||||
}
|
||||
|
||||
|
||||
/* key the keys from the cmd line */
|
||||
static ldns_rr_list *
|
||||
open_keyfiles(char **files, uint16_t filec)
|
||||
{
|
||||
uint16_t i;
|
||||
ldns_rr_list *pubkeys;
|
||||
ldns_rr *k;
|
||||
FILE *kfp;
|
||||
|
||||
pubkeys = ldns_rr_list_new();
|
||||
|
||||
for (i = 0; i < filec; i++) {
|
||||
if (!(kfp = fopen(files[i], "r"))) {
|
||||
fprintf(stderr, "Error opening key file %s: %s\n", files[i], strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (ldns_rr_new_frm_fp(&k, kfp, NULL, NULL, NULL) != LDNS_STATUS_OK) {
|
||||
fprintf(stderr, "Error parsing the key file %s: %s\n", files[i], strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
fclose(kfp);
|
||||
ldns_rr_list_push_rr(pubkeys, k);
|
||||
}
|
||||
return pubkeys;
|
||||
}
|
||||
|
||||
/* open a new zone file with the correct suffix */
|
||||
static FILE *
|
||||
open_newfile(char *basename, ldns_zone *z, size_t counter, ldns_rr_list *keys)
|
||||
{
|
||||
char filename[FILE_SIZE];
|
||||
FILE *fp;
|
||||
|
||||
if (counter > SPLIT_MAX) {
|
||||
fprintf(stderr, "Maximum split count reached %u\n", (unsigned int) counter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(filename, FILE_SIZE, "%s.%03u", basename, (unsigned int) counter);
|
||||
|
||||
if (!(fp = fopen(filename, "w"))) {
|
||||
fprintf(stderr, "Cannot open zone %s: %s\n", filename, strerror(errno));
|
||||
return NULL;
|
||||
} else {
|
||||
fprintf(stderr, "%s\n", filename);
|
||||
}
|
||||
ldns_rr_print(fp, ldns_zone_soa(z));
|
||||
if (keys) {
|
||||
ldns_rr_list_print(fp, keys);
|
||||
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *progname;
|
||||
FILE *fp;
|
||||
ldns_zone *z;
|
||||
ldns_rr_list *zrrs;
|
||||
ldns_rdf *lastname;
|
||||
int c;
|
||||
int line_nr;
|
||||
size_t split;
|
||||
size_t i;
|
||||
int splitting;
|
||||
int compare;
|
||||
size_t file_counter;
|
||||
ldns_rdf *origin;
|
||||
ldns_rdf *current_rdf;
|
||||
ldns_rr *current_rr;
|
||||
ldns_rr_list *last_rrset;
|
||||
ldns_rr_list *pubkeys;
|
||||
bool sort;
|
||||
ldns_status s;
|
||||
|
||||
progname = strdup(argv[0]);
|
||||
split = 0;
|
||||
splitting = NO_SPLIT;
|
||||
file_counter = 0;
|
||||
lastname = NULL;
|
||||
origin = NULL;
|
||||
last_rrset = ldns_rr_list_new();
|
||||
sort = false;
|
||||
|
||||
while ((c = getopt(argc, argv, "n:o:zv")) != -1) {
|
||||
switch(c) {
|
||||
case 'n':
|
||||
split = (size_t)atoi(optarg);
|
||||
if (split == 0) {
|
||||
fprintf(stderr, "-n want a integer\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
origin = ldns_dname_new_frm_str(strdup(optarg));
|
||||
if (!origin) {
|
||||
fprintf(stderr, "Cannot convert the origin %s to a domainname\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
printf("zone file splitter version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'z':
|
||||
sort = true;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognized option\n");
|
||||
usage(stdout, progname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (split == 0) {
|
||||
split = DEFAULT_SPLIT;
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1) {
|
||||
usage(stdout, progname);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!(fp = fopen(argv[0], "r"))) {
|
||||
fprintf(stderr, "Unable to open %s: %s\n", argv[0], strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* get the keys */
|
||||
pubkeys = open_keyfiles(argv + 1, (uint16_t) argc - 1);
|
||||
|
||||
/* suck in the entire zone ... */
|
||||
if (!origin) {
|
||||
origin = ldns_dname_new_frm_str(".");
|
||||
}
|
||||
|
||||
s = ldns_zone_new_frm_fp_l(&z, fp, origin, 0, LDNS_RR_CLASS_IN, &line_nr);
|
||||
fclose(fp);
|
||||
|
||||
if (s != LDNS_STATUS_OK) {
|
||||
fprintf(stderr, "Zone file %s could not be parsed correctly: %s at line %d\n",
|
||||
argv[0],
|
||||
ldns_get_errorstr_by_id(s),
|
||||
line_nr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
/* these kind of things can kill you... */
|
||||
if (sort) {
|
||||
ldns_zone_sort(z);
|
||||
}
|
||||
|
||||
zrrs = ldns_zone_rrs(z);
|
||||
if (ldns_rr_list_rr_count(zrrs) / split > SPLIT_MAX) {
|
||||
fprintf(stderr, "The zone is too large for the used -n value: %u\n", (unsigned int) split);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/* Setup */
|
||||
if (!(fp = open_newfile(argv[0], z, file_counter, pubkeys))) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for(i = 0; i < ldns_rr_list_rr_count(zrrs); i++) {
|
||||
|
||||
current_rr = ldns_rr_list_rr(zrrs, i);
|
||||
current_rdf = ldns_rr_owner(current_rr);
|
||||
|
||||
compare = ldns_dname_compare(current_rdf, lastname);
|
||||
|
||||
if (compare == 0) {
|
||||
ldns_rr_list_push_rr(last_rrset, current_rr);
|
||||
}
|
||||
|
||||
if (i > 0 && (i % split) == 0) {
|
||||
splitting = INTENT_TO_SPLIT;
|
||||
}
|
||||
|
||||
if (splitting == INTENT_TO_SPLIT) {
|
||||
if (compare != 0) {
|
||||
splitting = SPLIT_NOW;
|
||||
}
|
||||
}
|
||||
|
||||
if (splitting == SPLIT_NOW) {
|
||||
fclose(fp);
|
||||
|
||||
lastname = NULL;
|
||||
splitting = NO_SPLIT;
|
||||
file_counter++;
|
||||
if (!(fp = open_newfile(argv[0], z, file_counter, pubkeys))) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* insert the last RRset in the new file */
|
||||
ldns_rr_list_print(fp, last_rrset);
|
||||
|
||||
/* print the current rr */
|
||||
ldns_rr_print(fp, current_rr);
|
||||
|
||||
/* remove them */
|
||||
ldns_rr_list_free(last_rrset);
|
||||
last_rrset = ldns_rr_list_new();
|
||||
/* add the current RR */
|
||||
ldns_rr_list_push_rr(last_rrset, current_rr);
|
||||
continue;
|
||||
}
|
||||
if (splitting == NO_SPLIT || splitting == INTENT_TO_SPLIT) {
|
||||
ldns_rr_print(fp, current_rr);
|
||||
}
|
||||
if (compare != 0) {
|
||||
/* remove them and then add the current one */
|
||||
ldns_rr_list_free(last_rrset);
|
||||
last_rrset = ldns_rr_list_new();
|
||||
ldns_rr_list_push_rr(last_rrset, current_rr);
|
||||
}
|
||||
lastname = current_rdf;
|
||||
}
|
||||
fclose(fp);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
Reference in New Issue
Block a user