[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] branch master updated: -cleanup and make zonefile parsing more
From: |
gnunet |
Subject: |
[gnunet] branch master updated: -cleanup and make zonefile parsing more robust |
Date: |
Thu, 20 Oct 2022 04:25:22 +0200 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 03c7d8ec0 -cleanup and make zonefile parsing more robust
03c7d8ec0 is described below
commit 03c7d8ec09d7e294bacd1aa1e5e61692d686629c
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Thu Oct 20 11:25:01 2022 +0900
-cleanup and make zonefile parsing more robust
---
src/namestore/example_zonefile | 2 +
src/namestore/gnunet-namestore-zonefile.c | 191 ++++++++++++++++++++++--------
2 files changed, 146 insertions(+), 47 deletions(-)
diff --git a/src/namestore/example_zonefile b/src/namestore/example_zonefile
index d75adcbde..0564368e8 100644
--- a/src/namestore/example_zonefile
+++ b/src/namestore/example_zonefile
@@ -2,6 +2,7 @@ $ORIGIN example.com. ; designates the start of this zone
file in the namespa
$TTL 3600 ; default expiration time (in seconds) of all RRs
without their own TTL value
example.com. IN SOA ns.example.com. username.example.com. ( 2020091025 ;
A comment
7200 ;
Comment
+ ; empty line
on purpose
3600
1209600
3600 )
@@ -19,4 +20,5 @@ wwwtest IN CNAME www ;
wwwtest.example.com is another
mail IN A 192.0.2.3 ; IPv4 address for
mail.example.com
mail2 IN A 192.0.2.4 ; IPv4 address for
mail2.example.com
mail3 IN A 192.0.2.5 ; IPv4 address for
mail3.example.com
+
mail3 IN TXT "This is ; quoted" ; A quoted comment separator
diff --git a/src/namestore/gnunet-namestore-zonefile.c
b/src/namestore/gnunet-namestore-zonefile.c
index 22ae4a9f5..733cdb380 100644
--- a/src/namestore/gnunet-namestore-zonefile.c
+++ b/src/namestore/gnunet-namestore-zonefile.c
@@ -27,6 +27,29 @@
#include <gnunet_util_lib.h>
#include <gnunet_namestore_plugin.h>
+#define MAX_RECORDS_PER_NAME 50
+
+/**
+ * Maximum length of a zonefile line
+ */
+#define MAX_ZONEFILE_LINE_LEN 4096
+
+/**
+ * FIXME: Soft limit this?
+ */
+#define MAX_ZONEFILE_RECORD_DATA_LEN 2048
+
+/**
+ * The record data under a single label. Reused.
+ * Hard limit.
+ */
+static struct GNUNET_GNSRECORD_Data rd[MAX_RECORDS_PER_NAME];
+
+/**
+ * Number of records for currently parsed set
+ */
+static unsigned int rd_count = 0;
+
/**
* Return code
*/
@@ -42,6 +65,16 @@ static char *ego_name = NULL;
*/
static char *res;
+/**
+ * Statistics, how many published record sets
+ */
+static unsigned int published_sets = 0;
+
+/**
+ * Statistics, how many records published in aggregate
+ */
+static unsigned int published_records = 0;
+
/**
* Handle to identity lookup.
@@ -84,6 +117,11 @@ do_shutdown (void *cls)
GNUNET_NAMESTORE_cancel (ns_qe);
if (NULL != ns)
GNUNET_NAMESTORE_disconnect (ns);
+ for (int i = 0; i < rd_count; i++)
+ {
+ void *rd_ptr = (void*) rd[i].data;
+ GNUNET_free (rd_ptr);
+ }
}
@@ -162,6 +200,42 @@ next_token (char *token)
return next;
}
+static int
+parse_ttl (char *token, struct GNUNET_TIME_Relative *ttl)
+{
+ char *next;
+ unsigned int ttl_tmp;
+
+ next = strchr (token, ';');
+ if (NULL != next)
+ next[0] = '\0';
+ next = strchr (token, ' ');
+ if (NULL != next)
+ next[0] = '\0';
+ if (1 != sscanf (token, "%u", &ttl_tmp))
+ {
+ fprintf (stderr, "Unable to parse TTL `%s'\n", token);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TTL is: %u\n", ttl_tmp);
+ ttl->rel_value_us = ttl_tmp * 1000 * 1000;
+ return GNUNET_OK;
+}
+
+static int
+parse_origin (char *token, char *origin)
+{
+ char *next;
+ next = strchr (token, ';');
+ if (NULL != next)
+ next[0] = '\0';
+ next = strchr (token, ' ');
+ if (NULL != next)
+ next[0] = '\0';
+ strcpy (origin, token);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin is: %s\n", origin);
+}
+
/**
* Main function that will be run.
*
@@ -181,40 +255,38 @@ next_token (char *token)
static void
parse (void *cls)
{
- static struct GNUNET_GNSRECORD_Data rd[50]; // Let's hope we do not need more
- char buf[5000]; /* buffer to hold entire line (adjust MAXC as needed) */
- char payload[5000];
+ char buf[MAX_ZONEFILE_LINE_LEN];
+ char payload[MAX_ZONEFILE_RECORD_DATA_LEN];
char *next;
char *token;
char *payload_pos;
- char origin[255];
- static char lastname[255];
- char newname[255];
+ char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
+ static char lastname[GNUNET_DNSPARSER_MAX_LABEL_LENGTH];
+ char newname[GNUNET_DNSPARSER_MAX_LABEL_LENGTH];
void *data;
size_t data_size;
struct GNUNET_TIME_Relative ttl;
int origin_line = 0;
int ttl_line = 0;
int type;
- static unsigned int rd_count = 0;
- uint32_t ttl_tmp;
int name_changed = 0;
int bracket_unclosed = 0;
int quoted = 0;
- static unsigned int published_sets = 0;
- static unsigned int published_records = 0;
/* use filename provided as 1st argument (stdin by default) */
int i = 0;
- while (res = fgets (buf, 5000, stdin)) /* read each line
of input */
+ while (res = fgets (buf, sizeof(buf), stdin)) /* read
each line of input */
{
i++;
origin_line = 0;
ttl_line = 0;
token = trim (buf);
- printf ("Trimmed line (bracket %s): `%s'\n",
- (bracket_unclosed > 0) ? "unclosed" : "closed",
- token);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Trimmed line (bracket %s): `%s'\n",
+ (bracket_unclosed > 0) ? "unclosed" : "closed",
+ token);
+ if ((1 == strlen (token)) && (' ' == *token))
+ continue; // I guess we can safely ignore blank lines
if (bracket_unclosed == 0)
{
/* Payload is already parsed */
@@ -240,22 +312,31 @@ parse (void *cls)
}
else
{
- printf ("TOKEN: %s\n", token);
if (0 == strcmp (token, "IN")) // Inherit name from before
{
- printf ("Old name: %s\n", lastname);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Old name: %s\n", lastname);
strcpy (newname, lastname);
token[strlen (token)] = ' ';
}
else if (token[strlen (token) - 1] != '.') // no fqdn
{
- printf ("New name: %s\n", token);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New name: %s\n", token);
+ if (GNUNET_DNSPARSER_MAX_LABEL_LENGTH < strlen (token))
+ {
+ fprintf (stderr,
+ _ ("Name `%s' is too long\n"),
+ token);
+ ret = 1;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
strcpy (newname, token);
token = next_token (next);
}
else if (0 == strcmp (token, origin))
{
- printf ("New name: @\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New name: @\n");
strcpy (newname, "@");
token = next_token (next);
}
@@ -272,7 +353,16 @@ parse (void *cls)
break;
}
token[strlen (token) - strlen (origin) - 1] = '\0';
- printf ("New name: %s\n", token);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New name: %s\n", token);
+ if (GNUNET_DNSPARSER_MAX_LABEL_LENGTH < strlen (token))
+ {
+ fprintf (stderr,
+ _ ("Name `%s' is too long\n"),
+ token);
+ ret = 1;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
strcpy (newname, token);
token = next_token (next);
}
@@ -293,45 +383,48 @@ parse (void *cls)
if (ttl_line)
{
- next = strchr (token, ';');
- if (NULL != next)
- next[0] = '\0';
- next = strchr (token, ' ');
- if (NULL != next)
- next[0] = '\0';
- if (1 != sscanf (token, "%u", &ttl_tmp))
+ if (GNUNET_SYSERR == parse_ttl (token, &ttl))
{
- fprintf (stderr, "Unable to parse TTL `%s'\n", token);
- break;
+ ret = 1;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
}
- printf ("TTL is: %u\n", ttl_tmp);
- ttl.rel_value_us = ttl_tmp * 1000 * 1000;
continue;
}
if (origin_line)
{
- next = strchr (token, ';');
- if (NULL != next)
- next[0] = '\0';
- next = strchr (token, ' ');
- if (NULL != next)
- next[0] = '\0';
- strcpy (origin, token);
- printf ("Origin is: %s\n", origin);
+ if (GNUNET_SYSERR == parse_origin (token, origin))
+ {
+ ret = 1;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
continue;
}
// This is a record, let's go
+ if (MAX_RECORDS_PER_NAME == rd_count)
+ {
+ fprintf (stderr,
+ _ ("Only %u records per unique name supported.\n"),
+ MAX_RECORDS_PER_NAME);
+ ret = 1;
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+
+ }
rd[rd_count].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
rd[rd_count].expiration_time = ttl.rel_value_us;
next = strchr (token, ' ');
if (NULL == next)
{
fprintf (stderr, "Error, last token: %s\n", token);
+ ret = 1;
+ GNUNET_SCHEDULER_shutdown ();
break;
}
next[0] = '\0';
next++;
- printf ("class is: %s\n", token);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "class is: %s\n", token);
while (*next == ' ')
next++;
token = next;
@@ -343,7 +436,7 @@ parse (void *cls)
}
next[0] = '\0';
next++;
- printf ("type is: %s\n", token);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "type is: %s\n", token);
type = GNUNET_GNSRECORD_typename_to_number (token);
rd[rd_count].record_type = type;
while (*next == ' ')
@@ -368,13 +461,12 @@ parse (void *cls)
continue;
}
*payload_pos = '\0';
- printf ("data is: %s\n\n", payload);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "data is: %s\n\n", payload);
if (GNUNET_OK !=
GNUNET_GNSRECORD_string_to_value (type, payload,
&data,
&data_size))
{
- // FIXME free rd
fprintf (stderr,
_ ("Data `%s' invalid\n"),
payload);
@@ -399,13 +491,18 @@ parse (void *cls)
NULL);
published_sets++;
published_records += rd_count;
- // FIXME cleanup rd
+ for (int i = 0; i < rd_count; i++)
+ {
+ data = (void*) rd[i].data;
+ GNUNET_free (data);
+ }
if (name_changed)
{
- rd[0] = rd[rd_count]; // recover last rd parsed.
- rd_count = 1;
- strcpy (lastname, newname);
- } else
+ rd[0] = rd[rd_count]; // recover last rd parsed.
+ rd_count = 1;
+ strcpy (lastname, newname);
+ }
+ else
rd_count = 0;
return;
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: -cleanup and make zonefile parsing more robust,
gnunet <=