Update DDDS/DNS support.

This commit is contained in:
bossiel 2010-01-26 19:33:33 +00:00
parent edfef1c6a2
commit c453910507
16 changed files with 943 additions and 43 deletions

View File

@ -18,4 +18,175 @@
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
*/
/**@file tnet_dns.c
* @brief DNS utilities functions (RFCS [1034 1035] [3401 3402 3403 3404]).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#include "tnet_dns.h"
#include "tnet_dns_message.h"
#include "tnet_types.h"
#include "tsk_memory.h"
#include "tsk_time.h"
#include "tsk_debug.h"
tnet_dns_response_t *tnet_dns_resolve(tnet_dns_t* ctx, const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype)
{
tsk_buffer_t *output = 0;
tnet_dns_query_t* query = TNET_DNS_QUERY_CREATE(qname, qclass, qtype);
tnet_dns_response_t *response = 0;
/* Set user preference */
query->Header.RD = ctx->enable_recursion;
/* Serialize and send to the server. */
output = tnet_dns_message_serialize(query);
{
/* FIXME */
int ret;
struct timeval tv;
fd_set set;
uint64_t timeout = 0;
tsk_list_item_t *item;
const tnet_address_t *address;
struct sockaddr_storage server;
tnet_socket_t *localsocket = TNET_SOCKET_CREATE(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv4);
/* Check socket validity */
if(!TNET_SOCKET_IS_VALID(localsocket))
{
goto done;
}
/* Always wait for 300ms before retransmission */
tv.tv_sec = 0;
tv.tv_usec = (300 * 1000);
/* Set FD */
FD_ZERO(&set);
FD_SET(localsocket->fd, &set);
do
{
tsk_list_foreach(item, ctx->servers)
{
address = item->data;
if(!address->ip || address->family != AF_INET) continue; /* FIXME: for now I only support IPv4. */
if(tnet_sockaddr_init(address->ip, 53, tnet_socket_type_udp_ipv4, &server))
{
TSK_DEBUG_ERROR("Failed to connect to this DNS server: \"%s\"", address->ip);
continue;
}
TSK_DEBUG_INFO("Send DNS query to \"%s\"", address->ip);
tnet_sockfd_sendto(localsocket->fd, (const struct sockaddr*)&server, output->data, output->size);
}
/* First time? ==> set timeout value */
if(!timeout) timeout = tsk_time_epoch() + ctx->timeout;
/* wait for response */
if((ret = select(localsocket->fd+1, &set, NULL, NULL, &tv))<0)
{ /* Error */
goto done;
}
else if(ret == 0)
{ /* timeout ==> do nothing */
}
else if(FD_ISSET(localsocket->fd, &set))
{ /* there is data to read */
size_t len = 0;
void* data = 0;
/* Check how how many bytes are pending */
if((ret = tnet_ioctlt(localsocket->fd, FIONREAD, &len))<0)
{
goto done;
}
/* Receive pending data */
data = tsk_calloc(len, sizeof(uint8_t));
if((ret = tnet_sockfd_recv(localsocket->fd, data, len, 0))<0)
{
TSK_FREE(data);
TSK_DEBUG_ERROR("Recving DNS dgrams failed with error code:%d", tnet_geterrno());
goto done;
}
/* Parse the incoming response. */
response = tnet_dns_message_deserialize(data, len);
TSK_FREE(data);
if(response)
{ /* response successfuly parsed */
if(query->Header.ID != response->Header.ID)
{ /* Not same transaction id ==> continue*/
TSK_OBJECT_SAFE_FREE(response);
}
else goto done;
}
}
}
while(timeout < tsk_time_epoch());
done:
TSK_OBJECT_SAFE_FREE(localsocket);
goto bail;
}
bail:
TSK_OBJECT_SAFE_FREE(query);
TSK_OBJECT_SAFE_FREE(output);
return response;
}
//========================================================
// [[DNS CONTEXT]] object definition
//
static void* tnet_dns_create(void * self, va_list * app)
{
tnet_dns_t *dns = self;
if(dns)
{
dns->timeout = TNET_DNS_TIMEOUT_DEFAULT;
dns->enable_recursion = 1;
dns->enable_edns0 = 1;
/* Gets all dns servers. */
dns->servers = tnet_get_addresses_all_dnsservers();
}
return self;
}
static void* tnet_dns_destroy(void * self)
{
tnet_dns_t *dns = self;
if(dns)
{
TSK_OBJECT_SAFE_FREE(dns->servers);
}
return self;
}
static const tsk_object_def_t tnet_dns_def_s =
{
sizeof(tnet_dns_t),
tnet_dns_create,
tnet_dns_destroy,
0,
};
const void *tnet_dns_def_t = &tnet_dns_def_s;

View File

@ -20,7 +20,7 @@
*
*/
/**@file tnet_dns.h
* @brief DNS utilities functions (RFCS [1034 1035] [3401 3402 3403 3404]).
* @brief DNS utilities functions (RFCS [1034 1035] [2671] [3401 3402 3403 3404]).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
@ -32,8 +32,35 @@
#include "tinyNET_config.h"
#include "tnet_dns_message.h"
#include "tnet_utils.h"
TNET_BEGIN_DECLS
#define TNET_DNS_CREATE() tsk_object_new(tnet_dns_def_t)
/** Default timeout (in milliseconds) value for DNS queries.
*/
#define TNET_DNS_TIMEOUT_DEFAULT 2000
typedef struct tnet_dns_s
{
TSK_DECLARE_OBJECT;
unsigned timeout; /**< In milliseconds. Default: @ref TNET_DNS_TIMEOUT_DEFAULT. */
unsigned enable_recursion:1; /**< Indicates whether to direct the name server to pursue the query recursively. Default: enabled.*/
unsigned enable_edns0:1; /**< Indicates whether to enable EDNS0 (Extension Mechanisms for DNS) or not. Default: enabled. */
tnet_addresses_L_t *servers;
}
tnet_dns_t;
TINYNET_API tnet_dns_response_t *tnet_dns_resolve(tnet_dns_t* ctx, const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype);
TINYNET_GEXTERN const void *tnet_dns_def_t;
TNET_END_DECLS

View File

@ -28,12 +28,199 @@
*/
#include "tnet_dns_message.h"
#include "../tnet_utils.h"
#include "tsk_memory.h"
#include "tsk_string.h"
#include "tsk_debug.h"
#include <string.h>
int tnet_dns_qname_serialize(const char* qname, tsk_buffer_t* output)
{
/*
QNAME a domain name represented as a sequence of labels, where
each label consists of a length octet followed by that
number of octets. The domain name terminates with the
zero length octet for the null label of the root. Note
that this field may be an odd number of octets; no
padding is used.
Example: "doubango.com" ==> 8doubango3comNULL
*/
static uint8_t null = 0;
char* _qname = tsk_strdup(qname);
char* label = strtok(_qname, ".");
while(label)
{
uint8_t length = strlen(label);
tsk_buffer_append(output, &length, 1);
tsk_buffer_append(output, label, strlen(label));
label = strtok (0, ".");
}
/* terminates domain name */
tsk_buffer_append(output, &null, 1);
TSK_FREE(_qname);
return 0;
}
tsk_buffer_t* tnet_dns_message_serialize(const tnet_dns_message_t *message)
{
tsk_buffer_t* output = 0;
uint16_t _2bytes;
/* Check message validity */
if(!message)
{
goto bail;
}
output = TSK_BUFFER_CREATE_NULL();
/* ==============================
* HEADER
*/
//tsk_buffer_append(output, &(message->Header), sizeof(message->Header));
/* ID */
_2bytes = ntohs(message->Header.ID);
tsk_buffer_append(output, &(_2bytes), 2);
/* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | */
{
uint16_t temp, _2bytes = 0;
temp = message->Header.QR, temp <<= 15;
_2bytes |= temp;
temp = message->Header.OPCODE, temp <<= 11;
_2bytes |= temp;
temp = message->Header.AA, temp <<= 10;
_2bytes |= temp;
temp = message->Header.TC, temp <<= 9;
_2bytes |= temp;
temp = message->Header.RD, temp <<= 8;
_2bytes |= temp;
temp = message->Header.RA, temp <<= 7;
_2bytes |= temp;
temp = message->Header.Z, temp <<= 4;
_2bytes |= temp;
temp = message->Header.RCODE, temp <<= 4;
_2bytes |= temp;
_2bytes = ntohs(_2bytes);
tsk_buffer_append(output, &(_2bytes), 2);
}
/* QDCOUNT */
_2bytes = ntohs(message->Header.QDCOUNT);
tsk_buffer_append(output, &(_2bytes), 2);
/* ANCOUNT */
_2bytes = ntohs(message->Header.ANCOUNT);
tsk_buffer_append(output, &(_2bytes), 2);
/* NSCOUNT */
_2bytes = ntohs(message->Header.NSCOUNT);
tsk_buffer_append(output, &(_2bytes), 2);
/* ARCOUNT */
_2bytes = ntohs(message->Header.ARCOUNT);
tsk_buffer_append(output, &(_2bytes), 2);
/* ==============================
* QUESTION
*/
if(TNET_DNS_MESSAGE_IS_QUERY(message))
{
/* QNAME */
tnet_dns_qname_serialize(message->Question.QNAME, output);
/* QTYPE */
_2bytes = ntohs(message->Question.QTYPE);
tsk_buffer_append(output, &(_2bytes), 2);
/* QCLASS */
_2bytes = ntohs(message->Question.QCLASS);
tsk_buffer_append(output, &(_2bytes), 2);
}
/* ==============================
* ANSWERS
*/
/* ==============================
* AUTHORITIES
*/
/* ==============================
* ADDITIONALS
*/
bail:
return output;
}
tnet_dns_message_t* tnet_dns_message_deserialize(const uint8_t *data, size_t size)
{
tnet_dns_message_t *message = 0;
uint8_t* dataPtr, *dataEnd;
if(!data || !size)
{
goto bail;
}
dataPtr = (uint8_t*)data;
dataEnd = (dataPtr + size);
message = TNET_DNS_MESSAGE_CREATE_NULL();
/* ==============================
* HEADER
*/
/* ID */
message->Header.ID = ntohs(*((uint16_t*)dataPtr));
dataPtr += 2;
/* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | */
{
uint16_t flags = ntohs(*((uint16_t*)dataPtr));
message->Header.QR = (flags >> 15);
message->Header.OPCODE = ((flags >> 11) & 0x000F);
message->Header.AA = ((flags >> 10) & 0x0001);
message->Header.TC = ((flags >> 9) & 0x0001);
message->Header.RD = ((flags >> 8) & 0x0001);
message->Header.RA = ((flags >> 7) & 0x0001);
message->Header.Z = ((flags >> 4) & 0x0007);
message->Header.RCODE = (flags & 0x000F);
dataPtr += 2;
}
/* QDCOUNT */
message->Header.QDCOUNT = ntohs(*((uint16_t*)dataPtr));
dataPtr += 2;
/* ANCOUNT */
message->Header.ANCOUNT = ntohs(*((uint16_t*)dataPtr));
dataPtr += 2;
/* NSCOUNT */
message->Header.NSCOUNT = ntohs(*((uint16_t*)dataPtr));
dataPtr += 2;
/* ARCOUNT */
message->Header.ARCOUNT = ntohs(*((uint16_t*)dataPtr));
dataPtr += 2;
bail:
return message;
}
//========================================================
// [[DNS MESSAGE]] object definition
@ -43,7 +230,31 @@ static void* tnet_dns_message_create(void * self, va_list * app)
tnet_dns_message_t *message = self;
if(message)
{
static uint16_t __dnsmessage_unique_id = 0;
const char* qname = va_arg(*app, const char*);
tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
tnet_dns_qtype_t qtype = va_arg(*app, tnet_dns_qtype_t);
unsigned isquery = va_arg(*app, unsigned);
/* Create random ID. */
message->Header.ID = ++__dnsmessage_unique_id;
/* QR field ==> query (0) - response (1) */
message->Header.QR = isquery ? 0 : 1;
if(isquery)
{
/* QDCOUNT field ==> at least one question */
message->Header.QDCOUNT = 1;
}
if(qname)
{
message->Question.QNAME = tsk_strdup(qname);
message->Question.QTYPE = qtype;
message->Question.QCLASS = qclass;
}
}
return self;
}
@ -56,7 +267,7 @@ static void* tnet_dns_message_destroy(void * self)
TSK_FREE(message->Question.QNAME);
TSK_OBJECT_SAFE_FREE(message->Answers);
TSK_OBJECT_SAFE_FREE(message->Authoritys);
TSK_OBJECT_SAFE_FREE(message->Authorities);
TSK_OBJECT_SAFE_FREE(message->Additionals);
}
return self;

View File

@ -34,8 +34,19 @@
#include "tnet_dns_rr.h"
#include "tsk_buffer.h"
TNET_BEGIN_DECLS
#define TNET_DNS_MESSAGE_CREATE(qname, qclass, qtype, isquery) tsk_object_new(tnet_dns_message_def_t, (const char*)qname, (tnet_dns_qclass_t)qclass, (tnet_dns_qtype_t)qtype, (unsigned)isquery)
#define TNET_DNS_MESSAGE_CREATE_NULL() TNET_DNS_MESSAGE_CREATE(0, qclass_any, qtype_any, 0)
#define TNET_DNS_RESPONSE_CREATE(qname, qclass, qtype) TNET_DNS_MESSAGE_CREATE(qname, qclass, qtype, 0)
#define TNET_DNS_QUERY_CREATE(qname, qclass, qtype) TNET_DNS_MESSAGE_CREATE(qname, qclass, qtype, 1)
#define TNET_DNS_MESSAGE_IS_RESPONSE(message) ((message)->Header.QR == 1)
#define TNET_DNS_MESSAGE_IS_QUERY(message) ((message)->Header.QR == 0)
/** Response code as per RFC 1035 subclause 4.1.1.
*/
typedef enum tnet_dns_rcode_e
@ -49,6 +60,16 @@ typedef enum tnet_dns_rcode_e
}
tnet_dns_rcode_t;
/** OPCODE defining the kind of query as per RFC 1035 subclause 4.1.1.
*/
typedef enum tnet_dns_opcode_e
{
opcode_query = 0, /**< 0 a standard query (QUERY) */
opcode_iquery = 1, /**< 1 an inverse query (IQUERY) */
opcode_status = 2, /**< 2 a server status request (STATUS) */
}
tnet_dns_opcode_t;
/** DNS message as per RFC 1035 subclause 4.
*/
typedef struct tnet_dns_message_s
@ -90,7 +111,7 @@ typedef struct tnet_dns_message_s
{
uint16_t ID;
unsigned QR:1;
unsigned OPCODE:4;
unsigned OPCODE:4; /* see @ref tnet_dns_opcode_t */
unsigned AA:1;
unsigned TC:1;
unsigned RD:1;
@ -126,11 +147,19 @@ typedef struct tnet_dns_message_s
Question;
tnet_dns_rrs_L_t *Answers;
tnet_dns_rrs_L_t *Authoritys;
tnet_dns_rrs_L_t *Authorities;
tnet_dns_rrs_L_t *Additionals;
}
tnet_dns_message_t;
typedef tnet_dns_message_t tnet_dns_query_t;
typedef tnet_dns_message_t tnet_dns_response_t;
tsk_buffer_t* tnet_dns_message_serialize(const tnet_dns_message_t *message);
tnet_dns_message_t* tnet_dns_message_deserialize(const uint8_t *data, size_t size);
TINYNET_GEXTERN const void *tnet_dns_message_def_t;
TNET_END_DECLS
#endif /* TNET_DNS_MESSAGE_H */

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou@yahoo.fr>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tnet_dns_opt.c
* @brief DNS OPT pseudo-RR (RFC 2671).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#include "tnet_dns_opt.h"
//========================================================
// [[DNS OPT]] object definition
//
static void* tnet_dns_opt_create(void * self, va_list * app)
{
tnet_dns_opt_t *rr_opt = self;
if(rr_opt)
{
/* init base */
tnet_dns_rr_init(TNET_DNS_RR(rr_opt), qtype_any, qclass_any);
}
return self;
}
static void* tnet_dns_opt_destroy(void * self)
{
tnet_dns_opt_t *rr_opt = self;
if(rr_opt)
{
/* deinit base */
tnet_dns_rr_deinit(TNET_DNS_RR(rr_opt));
}
return self;
}
static const tsk_object_def_t tnet_dns_opt_def_s =
{
sizeof(tnet_dns_opt_t),
tnet_dns_opt_create,
tnet_dns_opt_destroy,
0,
};
const void *tnet_dns_opt_def_t = &tnet_dns_opt_def_s;

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou@yahoo.fr>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tnet_dns_opt.h
* @brief DNS OPT pseudo-RR (RFC 2671).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#ifndef TNET_DNS_RR_OPT_H
#define TNET_DNS_RR_OPT_H
#include "tinyNET_config.h"
#include "tnet_dns_rr.h"
TNET_BEGIN_DECLS
#define TNET_DNS_OPT_CREATE(payload_size) tsk_object_new(tnet_dns_opt_def_t, (unsigned)payload_size)
typedef struct tnet_dns_opt_s
{
TNET_DECLARE_DNS_RR;
}
tnet_dns_opt_t;
TINYNET_GEXTERN const void *tnet_dns_opt_def_t;
TNET_END_DECLS
#endif /* TNET_DNS_RR_OPT_H */

View File

@ -28,7 +28,10 @@
*/
#include "tnet_dns_rr.h"
#include "../tnet_types.h"
#include "tsk_memory.h"
#include "tsk_debug.h"
int tnet_dns_rr_init(tnet_dns_rr_t *rr, tnet_dns_qtype_t qtype, tnet_dns_qclass_t qclass)
{
@ -64,8 +67,241 @@ int tnet_dns_rr_deinit(tnet_dns_rr_t *rr)
return -1;
}
tnet_dns_rr_t* tnet_dns_rr_deserialize(const void* data, size_t size)
{
tnet_dns_rr_t *rr = 0;
const uint8_t* dataPtr = data;
const uint8_t* dataEnd = (dataPtr+size);
tnet_dns_qtype_t qtype;
tnet_dns_qclass_t qclass;
char* qname = 0;
/* == Parse QNAME
*/
while(dataPtr && dataPtr<dataEnd)
{
/* FIXME: do .... */
dataPtr++;
if(!*dataPtr)
{
/* Terminator found. */
break;
}
}
/* Check validity */
if(dataPtr>=dataEnd)
{
goto bail;
}
qtype = (tnet_dns_qtype_t)ntohs(*((uint16_t*)dataPtr));
dataPtr += 2;
qclass = (tnet_dns_qclass_t)ntohs(*((uint16_t*)dataPtr));
dataPtr += 2;
switch(qtype)
{
case qtype_a:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_aaa:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_cname:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_mx:
{
break;
}
case qtype_naptr:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_ns:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_opt:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_ptr:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_soa:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_srv:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_txt:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
default:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
}
bail:
TSK_FREE(qname);
return rr;
}
int tnet_dns_rr_serialize(const tnet_dns_rr_t* rr, tsk_buffer_t *output)
{
if(!rr || !output)
{
return -1;
}
/* NAME
*/
{
}
/* TYPE
*/
{
uint16_t qtype = htons(rr->qtype);
tsk_buffer_append(output, &(qtype), 2);
}
/* CLASS
*/
{
uint16_t qclass = htons(rr->qclass);
tsk_buffer_append(output, &(qclass), 2);
}
/* TTL
*/
{
uint32_t ttl = htonl(rr->ttl);
tsk_buffer_append(output, &(ttl), 4);
}
/* RDLENGTH
*/
{
uint16_t length = htons(rr->rdlength);
tsk_buffer_append(output, &(length), 2);
}
/* RDATA
*/
switch(rr->qtype)
{
case qtype_a:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_aaa:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_cname:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_mx:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_naptr:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_ns:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_opt:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_ptr:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_soa:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_srv:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
case qtype_txt:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
default:
{
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
break;
}
}
return -1;
}
//========================================================

View File

@ -33,36 +33,50 @@
#include "tinyNET_config.h"
#include "tsk_list.h"
#include "tsk_buffer.h"
TNET_BEGIN_DECLS
#define TNET_DNS_RR_CREATE() tsk_object_new(tnet_dns_rr_def_t)
#define TNET_DNS_RR(self) ((tnet_dns_rr_t*)(self))
/**
* RFC 1035 - 3.2.2. TYPE values
* @sa http://en.wikipedia.org/wiki/List_of_DNS_record_types
*/
typedef enum tnet_dns_qtype_e
{
qtype_a = 0x0001, /**< A 1 a host address */
qtype_ns = 0x0002, /**< NS 2 an authoritative name server */
qtype_md = 0x0003, /**< MD 3 a mail destination (Obsolete - use MX) */
qtype_mf = 0x0004, /**< MF 4 a mail forwarder (Obsolete - use MX) */
qtype_cname = 0x0005, /**< CNAME 5 the canonical name for an alias */
qtype_soa = 0x0006, /**< SOA 6 marks the start of a zone of authority */
qtype_mb = 0x0007, /**< MB 7 a mailbox domain name (EXPERIMENTAL) */
qtype_mg = 0x0008, /**< MG 8 a mail group member (EXPERIMENTAL) */
qtype_mr = 0x0009, /**< MR 9 a mail rename domain name (EXPERIMENTAL) */
qtype_null = 0x000a, /**< NULL 10 a null RR (EXPERIMENTAL) */
qtype_wks = 0x000b, /**< WKS 11 a well known service description */
qtype_ptr = 0x000c, /**< PTR 12 a domain name pointer */
qtype_hinfo = 0x000d, /**< HINFO 13 host information */
qtype_minfo = 0x000e, /**< MINFO 14 mailbox or mail list information */
qtype_mx = 0x000f, /**< MX 15 mail exchange */
qtype_txt = 0x0010, /**< TXT 16 text strings */
qtype_a = 1, /**< A 1 a host address */
qtype_ns = 2, /**< NS 2 an authoritative name server */
qtype_md = 3, /**< MD 3 a mail destination (Obsolete - use MX) */
qtype_mf = 4, /**< MF 4 a mail forwarder (Obsolete - use MX) */
qtype_cname = 5, /**< CNAME 5 the canonical name for an alias */
qtype_soa = 6, /**< SOA 6 marks the start of a zone of authority */
qtype_mb = 7, /**< MB 7 a mailbox domain name (EXPERIMENTAL) */
qtype_mg = 8, /**< MG 8 a mail group member (EXPERIMENTAL) */
qtype_mr = 9, /**< MR 9 a mail rename domain name (EXPERIMENTAL) */
qtype_null = 10, /**< NULL 10 a null RR (EXPERIMENTAL) */
qtype_wks = 11, /**< WKS 11 a well known service description */
qtype_ptr = 12, /**< PTR 12 a domain name pointer */
qtype_hinfo = 13, /**< HINFO 13 host information */
qtype_minfo = 14, /**< MINFO 14 mailbox or mail list information */
qtype_mx = 15, /**< MX 15 mail exchange */
qtype_txt = 16, /**< TXT 16 text strings */
qtype_aaa = 0x001c, /**< AAAA 28 IPv6 host address */
qtype_aaa = 28, /**< AAAA 28 IPv6 host address */
qtype_any = 0x00ff /**< * 255 A request for all records (3.2.3. QTYPE values)*/
qtype_srv = 33, /**< SRV 33 Service locator */
qtype_naptr = 35, /**< NAPTR 35 Naming Authority Pointer */
qtype_opt = 41, /**< OPT 41 Option */
qtype_ipseckey = 45,/**< IPSECKEY 45 IPSEC Key */
qtype_spf = 99, /**< SPF 99 SPF record */
qtype_any = 255 /**< * 255 A request for all records (3.2.3. QTYPE values)*/
}
tnet_dns_qtype_t;
@ -71,12 +85,12 @@ tnet_dns_qtype_t;
*/
typedef enum tnet_dns_qclass_e
{
qclass_in = 0x0001, /**< IN 1 the Internet */
qclass_ics = 0x0002, /**< CS 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
qclass_ch = 0x0003, /**< CH 3 the CHAOS class */
qclass_hs = 0x0004, /**< HS 4 Hesiod [Dyer 87] */
qclass_in = 1, /**< IN 1 the Internet */
qclass_ics = 2, /**< CS 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
qclass_ch = 3, /**< CH 3 the CHAOS class */
qclass_hs = 4, /**< HS 4 Hesiod [Dyer 87] */
qclass_any = 0x00ff /**< * 255 any class (3.2.5. QCLASS values) */
qclass_any = 255 /**< * 255 any class (3.2.5. QCLASS values) */
}
tnet_dns_qclass_t;
@ -135,11 +149,17 @@ typedef struct tnet_dns_rr_s
void *rpdata;
}
tnet_dns_rr_t;
#define TNET_DECLARE_DNS_RR tnet_dns_rr_t dns_rr
typedef tsk_list_t tnet_dns_rrs_L_t;
int tnet_dns_rr_init(tnet_dns_rr_t *rr, tnet_dns_qtype_t qtype, tnet_dns_qclass_t qclass);
int tnet_dns_rr_deinit(tnet_dns_rr_t *rr);
tnet_dns_rr_t* tnet_dns_rr_deserialize(const void* data, size_t size);
int tnet_dns_rr_serialize(const tnet_dns_rr_t* rr, tsk_buffer_t *output);
TINYNET_GEXTERN const void *tnet_dns_rr_def_t;
TNET_END_DECLS

View File

View File

@ -122,7 +122,7 @@ tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO,
fd_set set;
tsk_buffer_t *buffer = tnet_stun_message_serialize(message);
tnet_stun_response_t *reponse = 0;
tnet_stun_response_t *response = 0;
if(!buffer)
{
@ -202,14 +202,14 @@ tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO,
}
/* Parse the incoming response. */
reponse = tnet_stun_message_deserialize(data, len);
response = tnet_stun_message_deserialize(data, len);
TSK_FREE(data);
if(reponse)
if(response)
{
if(tnet_stun_transacid_cmp(message->transaction_id, reponse->transaction_id))
if(tnet_stun_transacid_cmp(message->transaction_id, response->transaction_id))
{ /* Not same transaction id */
TSK_OBJECT_SAFE_FREE(reponse);
TSK_OBJECT_SAFE_FREE(response);
continue;
}
}
@ -222,7 +222,7 @@ tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO,
bail:
TSK_OBJECT_SAFE_FREE(buffer);
return reponse;
return response;
}
/**

View File

@ -162,7 +162,7 @@ bail:
return ifaces;
}
tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family)
tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, unsigned unicast, unsigned anycast, unsigned multicast, unsigned dnsserver)
{
tnet_addresses_L_t *addresses = TSK_LIST_CREATE();
tnet_ip_t ip;
@ -221,7 +221,7 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family)
/* UNICAST addresses
*/
pUnicast = pCurrAddresses->FirstUnicastAddress;
while(pUnicast)
while(unicast && pUnicast)
{
memset(ip, '\0', sizeof(ip));
tnet_get_sockip(pUnicast->Address.lpSockaddr, &ip);
@ -238,7 +238,7 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family)
/* ANYCAST addresses
*/
pAnycast = pCurrAddresses->FirstAnycastAddress;
while(pAnycast)
while(anycast && pAnycast)
{
memset(ip, '\0', sizeof(ip));
tnet_get_sockip(pAnycast->Address.lpSockaddr, &ip);
@ -255,7 +255,7 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family)
/* MULTYCAST addresses
*/
pMulticast = pCurrAddresses->FirstMulticastAddress;
while(pMulticast)
while(multicast && pMulticast)
{
memset(ip, '\0', sizeof(ip));
tnet_get_sockip(pMulticast->Address.lpSockaddr, &ip);
@ -272,7 +272,7 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family)
/* DNS servers
*/
pDnServer = pCurrAddresses->FirstDnsServerAddress;
while(pDnServer)
while(dnsserver && pDnServer)
{
memset(ip, '\0', sizeof(ip));
tnet_get_sockip(pDnServer->Address.lpSockaddr, &ip);

View File

@ -71,8 +71,20 @@ TINYNET_API void tnet_getlasterror(tnet_error_t *error);
TINYNET_API int tnet_geterrno();
TINYNET_API tnet_interfaces_L_t* tnet_get_interfaces();
TINYNET_API tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family);
#define tnet_get_addresses_all() tnet_get_addresses(AF_UNSPEC)
TINYNET_API tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, unsigned unicast, unsigned anycast, unsigned multicast, unsigned dnsserver);
#define tnet_get_addresses_all() tnet_get_addresses(AF_UNSPEC, 1, 1, 1, 1)
#define tnet_get_addresses_all_unicast() tnet_get_addresses(AF_UNSPEC, 1, 0, 0, 0)
#define tnet_get_addresses_unicast4() tnet_get_addresses(AF_INET, 1, 0, 0, 0)
#define tnet_get_addresses_unicast6() tnet_get_addresses(AF_INET6, 1, 0, 0, 0)
#define tnet_get_addresses_all_anycast() tnet_get_addresses(AF_UNSPEC, 0, 1, 0, 0)
#define tnet_get_addresses_anycast4() tnet_get_addresses(AF_INET, 0, 1, 0, 0)
#define tnet_get_addresses_anycast6() tnet_get_addresses(AF_INET6, 0, 1, 0, 0)
#define tnet_get_addresses_all_multicast() tnet_get_addresses(AF_UNSPEC, 0, 0, 1, 0)
#define tnet_get_addresses_multicast4() tnet_get_addresses(AF_INET, 0, 0, 1, 0)
#define tnet_get_addresses_multicast6() tnet_get_addresses(AF_INET6, 0, 0, 1, 0)
#define tnet_get_addresses_all_dnsservers() tnet_get_addresses(AF_UNSPEC, 0, 0, 0, 1)
#define tnet_get_addresses_dnsservers4() tnet_get_addresses(AF_INET, 0, 0, 0, 1)
#define tnet_get_addresses_dnsservers6() tnet_get_addresses(AF_INET6, 0, 0, 0, 1)
TINYNET_API int tnet_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
TINYNET_API void tnet_freeaddrinfo(struct addrinfo *ai);

View File

@ -28,6 +28,7 @@
#include "tnet_socket.h"
#include "tnet_transport.h"
#include "stun/tnet_stun.h"
#include "dns/tnet_dns.h"
#include "test_sockets.h"
#include "test_transport.h"
@ -35,16 +36,18 @@
#include "test_stun.h"
#include "test_nat.h"
#include "test_ifaces.h"
#include "test_dns.h"
#define RUN_TEST_LOOP 1
#define RUN_TEST_ALL 0
#define RUN_TEST_SOCKETS 0
#define RUN_TEST_TRANSPORT 1
#define RUN_TEST_TRANSPORT 0
#define RUN_TEST_AUTH 0
#define RUN_TEST_STUN 0
#define RUN_TEST_NAT 0
#define RUN_TEST_IFACES 0
#define RUN_TEST_DNS 1
#ifdef _WIN32_WCE
int _tmain(int argc, _TCHAR* argv[])
@ -87,6 +90,9 @@ int main()
test_ifaces();
#endif
#if RUN_TEST_ALL || RUN_TEST_DNS
test_dns();
#endif
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou@yahoo.fr>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#ifndef TNET_TEST_DNS_H
#define TNET_TEST_DNS_H
void test_dns_query()
{
tnet_dns_t *ctx = TNET_DNS_CREATE();
tnet_dns_response_t *response = 0;
response = tnet_dns_resolve(ctx, "ims.inexbee.com", qclass_in, qtype_naptr);
TSK_OBJECT_SAFE_FREE(response);
TSK_OBJECT_SAFE_FREE(ctx);
}
void test_dns()
{
test_dns_query();
}
#endif /* TNET_TEST_DNS_H */

View File

@ -370,6 +370,10 @@
RelativePath="..\..\tinyNET\test\test_auth.h"
>
</File>
<File
RelativePath="..\..\tinyNET\test\test_dns.h"
>
</File>
<File
RelativePath="..\..\tinyNET\test\test_nat.h"
>

View File

@ -448,6 +448,10 @@
RelativePath="..\..\tinyNET\src\dns\tnet_dns_ns.c"
>
</File>
<File
RelativePath="..\..\tinyNET\src\dns\tnet_dns_opt.c"
>
</File>
<File
RelativePath="..\..\tinyNET\src\dns\tnet_dns_ptr.c"
>
@ -460,6 +464,10 @@
RelativePath="..\..\tinyNET\src\dns\tnet_dns_soa.c"
>
</File>
<File
RelativePath="..\..\tinyNET\src\dns\tnet_dns_srv.c"
>
</File>
<File
RelativePath="..\..\tinyNET\src\dns\tnet_dns_txt.c"
>
@ -580,6 +588,10 @@
RelativePath="..\..\tinyNET\src\dns\tnet_dns_ns.h"
>
</File>
<File
RelativePath="..\..\tinyNET\src\dns\tnet_dns_opt.h"
>
</File>
<File
RelativePath="..\..\tinyNET\src\dns\tnet_dns_ptr.h"
>