Commit cfe80a2c authored by Lubos Slovak's avatar Lubos Slovak

Fixed dname API, added 3 functions, fixed impl.

dname and node were referencing each other. Used
  forward-declaration of node in dname.
Added API getter functions (with implementation):
  - dnslib_dname_name()
  - dnslib_dname_size()
  - dnslib_dname_node()
Fixed dname implementation:
  - str_to_wire() was replacing chars by label lengths
  - new_from_str() bad assert
  - new_from_wire() was not allocating space for the name
  - to_str() was de facto copying the wire format

Added some debug output to dname

refs #5, #88
parent fa2b8e5a
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "common.h"
#include "consts.h"
#include "dname.h"
......@@ -6,48 +9,84 @@
/*----------------------------------------------------------------------------*/
/* Non-API functions */
/*----------------------------------------------------------------------------*/
/*!
* \brief Returns the size of the wire format of domain name which has
* \a str_size characters in presentation format.
*/
static inline uint dnslib_dname_wire_size( uint str_size )
{
return str_size + 1;
}
/*----------------------------------------------------------------------------*/
/*!
* \brief Converts domain name from string representation to wire format.
*
* \param name Domain name in string representation (presentation format).
* \param size Size of the given domain name in characters (not counting the
* terminating 0 character.
* \param wire [in/out] Pointer to position where the wire format of the domain
* name will be stored.
*
* This function also allocates the space for the wire format.
*
* \return Size of the wire format of the domain name in octets. If 0, no
* space has been allocated.
*
* \todo handle \X and \DDD (RFC 1035 5.1) or it can be handled by the parser?
*/
int dnslib_dname_str_to_wire( const char *name, uint size, uint8_t **wire )
static uint dnslib_dname_str_to_wire( const char *name, uint size,
uint8_t **wire )
{
if (size > DNSLIB_MAX_DNAME_LENGTH) {
return 0;
}
uint wire_size = dnslib_dname_wire_size(size);
// signed / unsigned issues??
*wire = (uint8_t *)malloc((size + 1) * sizeof(uint8_t));
*wire = (uint8_t *)malloc(wire_size * sizeof(uint8_t));
if (*wire == NULL) {
return 0;
}
debug_dnslib_dname("Allocated space for wire format of dname: %p\n",
*wire);
const uint8_t *ch = (const uint8_t *)name;
uint8_t *label_start = *wire;
uint8_t *w = *wire;
uint8_t *w = *wire + 1;
uint8_t label_length = 0;
while (ch - name < size) {
assert(w - *wire < size);
assert(w - *wire == ch - name);
while (ch - (const uint8_t *)name < size) {
assert(w - *wire < wire_size);
assert(w - *wire - 1 == ch - (const uint8_t *)name);
if (*ch == '.' ) {
debug_dnslib_dname("Position %u (%p): label length: %u\n",
label_start - *wire, label_start, label_length);
*label_start = label_length;
label_start = w;
label_length = 0;
} else {
debug_dnslib_dname("Position %u (%p): character: %c\n",
w - *wire, w, *ch);
*w = *ch;
++label_length;
}
++w;
++ch;
assert(ch >= name);
assert(ch >= (const uint8_t *)name);
}
// put 0 for root label regardless whether the name ended with .
--w;
debug_dnslib_dname("Position %u (%p): character: (null)\n", w - *wire, w);
*w = 0;
//memcpy(*wire, name, size);
return size;
return wire_size;
}
/*----------------------------------------------------------------------------*/
......@@ -57,7 +96,7 @@ int dnslib_dname_str_to_wire( const char *name, uint size, uint8_t **wire )
dnslib_dname_t *dnslib_dname_new()
{
dnslib_dname_t *dname = (dnslib_dname_t *)malloc(sizeof(dnslib_dname_t));
if (name == NULL) {
if (dname == NULL) {
ERR_ALLOC_FAILED;
return NULL;
}
......@@ -72,7 +111,7 @@ dnslib_dname_t *dnslib_dname_new()
/*----------------------------------------------------------------------------*/
dnslib_dname_t *dnslib_dname_new_from_str( char *name, uint size,
dnslib_node_t *node )
struct dnslib_node *node )
{
if (name == NULL || size == 0) {
return NULL;
......@@ -89,6 +128,8 @@ dnslib_dname_t *dnslib_dname_new_from_str( char *name, uint size,
log_warning("Could not parse domain name from string: '%.*s'\n",
size, name);
}
assert(dname->name != NULL);
dname->node = node;
return dname;
......@@ -97,14 +138,26 @@ dnslib_dname_t *dnslib_dname_new_from_str( char *name, uint size,
/*----------------------------------------------------------------------------*/
dnslib_dname_t *dnslib_dname_new_from_wire( uint8_t *name, uint size,
dnslib_node_t *node )
struct dnslib_node *node )
{
if (name == NULL && size != 0) {
printf("No name given!\n");
return NULL;
}
dnslib_dname_t *dname = (dnslib_dname_t *)malloc(sizeof(dnslib_dname_t));
if (name == NULL) {
if (dname == NULL) {
ERR_ALLOC_FAILED;
return NULL;
}
dname->name = (uint8_t *)malloc(size * sizeof(uint8_t));
if (dname->name == NULL) {
ERR_ALLOC_FAILED;
free(dname);
return NULL;
}
memcpy(dname->name, name, size);
dname->size = size;
dname->node = node;
......@@ -114,7 +167,7 @@ dnslib_dname_t *dnslib_dname_new_from_wire( uint8_t *name, uint size,
/*----------------------------------------------------------------------------*/
char *dnslib_dname_to_str( dnslib_dname_t *dname )
char *dnslib_dname_to_str( const dnslib_dname_t *dname )
{
char *name = (char *)malloc(dname->size * sizeof(char));
......@@ -122,22 +175,46 @@ char *dnslib_dname_to_str( dnslib_dname_t *dname )
char *ch = name;
while (*w != 0) {
// skip label length
uint8_t *next = w + *w + 1;
// skip label length
++w;
while (w != next) {
*(ch++) = *(w++);
}
// insert . at the end of label
*(ch++) = '.';
}
*ch = 0;
assert(ch - name == dname->size);
assert(ch - name == dname->size - 1);
return name;
}
/*----------------------------------------------------------------------------*/
void dnslib_dname_free( dnslib_dname *dname )
const uint8_t *dnslib_dname_name( const dnslib_dname_t *dname )
{
return dname->name;
}
/*----------------------------------------------------------------------------*/
uint dnslib_dname_size( const dnslib_dname_t *dname )
{
return dname->size;
}
/*----------------------------------------------------------------------------*/
const struct dnslib_node *dnslib_dname_node( const dnslib_dname_t *dname )
{
return dname->node;
}
/*----------------------------------------------------------------------------*/
void dnslib_dname_free( dnslib_dname_t *dname )
{
free(dname->name);
free(dname);
......
......@@ -3,7 +3,8 @@
#include <stdint.h>
#include "common.h"
#include "node.h"
struct dnslib_node;
/*----------------------------------------------------------------------------*/
/*!
......@@ -20,10 +21,10 @@ struct dnslib_dname {
* \todo Is this needed? Every dname should end with \0 or pointer.
*/
uint size;
dnslib_node_t *node; /*!< Zone node the domain name belongs to. */
struct dnslib_node *node; /*!< Zone node the domain name belongs to. */
};
typedef struct dname dnslib_dname_t;
typedef struct dnslib_dname dnslib_dname_t;
/*----------------------------------------------------------------------------*/
......@@ -53,13 +54,15 @@ dnslib_dname_t *dnslib_dname_new();
* \todo Check if the FQDN issue is OK.
*/
dnslib_dname_t *dnslib_dname_new_from_str( char *name, uint size,
dnslib_node_t *node );
struct dnslib_node *node );
/*!
* \brief Creates a dname structure from domain name given in wire format.
*
* \param name Domain name in wire format.
* \param size Size of the domain name in octets.
* \param node Zone node the domain name belongs to. Set to NULL if not
* applicable.
*
* \return Newly allocated and initialized dname structure representing the
* given domain name.
......@@ -69,7 +72,8 @@ dnslib_dname_t *dnslib_dname_new_from_str( char *name, uint size,
* does not correspond to the behaviour of dnslib_dname_new_from_str().
* \todo Address the FQDN issue.
*/
dnslib_dname_t *dnslib_dname_new_from_wire( uint8_t *name, uint size );
dnslib_dname_t *dnslib_dname_new_from_wire( uint8_t *name, uint size,
struct dnslib_node *node );
/*!
* \brief Converts the given domain name to string representation.
......@@ -80,7 +84,34 @@ dnslib_dname_t *dnslib_dname_new_from_wire( uint8_t *name, uint size );
* presentation format.
* \note Allocates new memory, remember to free it.
*/
char *dnslib_dname_to_str( dnslib_dname_t *dname );
char *dnslib_dname_to_str( const dnslib_dname_t *dname );
/*!
* \brief Returns the domain name in wire format.
*
* \param dname Domain name.
*
* \return Wire format of the domain name.
*/
const uint8_t *dnslib_dname_name( const dnslib_dname_t *dname );
/*!
* \brief Returns size of the given domain name.
*
* \param dname Domain name to get the size of.
*
* \return Size of the domain name in wire format in octets.
*/
uint dnslib_dname_size( const dnslib_dname_t *dname );
/*!
* \brief Returns the zone node the domain name belongs to.
*
* \param dname Domain name to get the zone node of.
*
* \return Zone node the domain name belongs to or NULL if none.
*/
const struct dnslib_node *dnslib_dname_node( const dnslib_dname_t *dname );
/*!
* \brief Destroys the given domain name.
......@@ -89,6 +120,6 @@ char *dnslib_dname_to_str( dnslib_dname_t *dname );
*
* \note Frees also the data within the struct.
*/
void dnslib_dname_free( dnslib_dname *dname );
void dnslib_dname_free( dnslib_dname_t *dname );
#endif /* _CUTEDNS_DNAME_H */
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