diff --git a/trunk/tinyNET/src/dns/tnet_dns.c b/trunk/tinyNET/src/dns/tnet_dns.c index 3eb01689..2b5a0c3f 100644 --- a/trunk/tinyNET/src/dns/tnet_dns.c +++ b/trunk/tinyNET/src/dns/tnet_dns.c @@ -18,4 +18,175 @@ * You should have received a copy of the GNU General Public License * along with DOUBANGO. * -*/ \ No newline at end of file +*/ +/**@file tnet_dns.c + * @brief DNS utilities functions (RFCS [1034 1035] [3401 3402 3403 3404]). + * + * @author Mamadou Diop + * + * @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; \ No newline at end of file diff --git a/trunk/tinyNET/src/dns/tnet_dns.h b/trunk/tinyNET/src/dns/tnet_dns.h index ad1956c4..e2cb21c4 100644 --- a/trunk/tinyNET/src/dns/tnet_dns.h +++ b/trunk/tinyNET/src/dns/tnet_dns.h @@ -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 * @@ -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 diff --git a/trunk/tinyNET/src/dns/tnet_dns_message.c b/trunk/tinyNET/src/dns/tnet_dns_message.c index 6fd4dbf3..8838c0d2 100644 --- a/trunk/tinyNET/src/dns/tnet_dns_message.c +++ b/trunk/tinyNET/src/dns/tnet_dns_message.c @@ -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 + +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; diff --git a/trunk/tinyNET/src/dns/tnet_dns_message.h b/trunk/tinyNET/src/dns/tnet_dns_message.h index a3d3ff62..00a569bf 100644 --- a/trunk/tinyNET/src/dns/tnet_dns_message.h +++ b/trunk/tinyNET/src/dns/tnet_dns_message.h @@ -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 */ diff --git a/trunk/tinyNET/src/dns/tnet_dns_opt.c b/trunk/tinyNET/src/dns/tnet_dns_opt.c new file mode 100644 index 00000000..3d5d713b --- /dev/null +++ b/trunk/tinyNET/src/dns/tnet_dns_opt.c @@ -0,0 +1,78 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* 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 + * + * @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; \ No newline at end of file diff --git a/trunk/tinyNET/src/dns/tnet_dns_opt.h b/trunk/tinyNET/src/dns/tnet_dns_opt.h new file mode 100644 index 00000000..2fc01e15 --- /dev/null +++ b/trunk/tinyNET/src/dns/tnet_dns_opt.h @@ -0,0 +1,52 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* 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 + * + * @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 */ \ No newline at end of file diff --git a/trunk/tinyNET/src/dns/tnet_dns_rr.c b/trunk/tinyNET/src/dns/tnet_dns_rr.c index c62716fc..59dfecf4 100644 --- a/trunk/tinyNET/src/dns/tnet_dns_rr.c +++ b/trunk/tinyNET/src/dns/tnet_dns_rr.c @@ -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) + { + 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; +} //======================================================== diff --git a/trunk/tinyNET/src/dns/tnet_dns_rr.h b/trunk/tinyNET/src/dns/tnet_dns_rr.h index 3d660b23..b6413ca3 100644 --- a/trunk/tinyNET/src/dns/tnet_dns_rr.h +++ b/trunk/tinyNET/src/dns/tnet_dns_rr.h @@ -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 diff --git a/trunk/tinyNET/src/dns/tnet_dns_srv.c b/trunk/tinyNET/src/dns/tnet_dns_srv.c new file mode 100644 index 00000000..e69de29b diff --git a/trunk/tinyNET/src/stun/tnet_stun.c b/trunk/tinyNET/src/stun/tnet_stun.c index 7454dc7f..7522107d 100644 --- a/trunk/tinyNET/src/stun/tnet_stun.c +++ b/trunk/tinyNET/src/stun/tnet_stun.c @@ -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; } /** diff --git a/trunk/tinyNET/src/tnet_utils.c b/trunk/tinyNET/src/tnet_utils.c index 9125c6b5..9e15c36e 100644 --- a/trunk/tinyNET/src/tnet_utils.c +++ b/trunk/tinyNET/src/tnet_utils.c @@ -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); diff --git a/trunk/tinyNET/src/tnet_utils.h b/trunk/tinyNET/src/tnet_utils.h index 8c486b74..0f3d59f7 100644 --- a/trunk/tinyNET/src/tnet_utils.h +++ b/trunk/tinyNET/src/tnet_utils.h @@ -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); diff --git a/trunk/tinyNET/test/test.c b/trunk/tinyNET/test/test.c index 769747f5..c222ebe4 100644 --- a/trunk/tinyNET/test/test.c +++ b/trunk/tinyNET/test/test.c @@ -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 } diff --git a/trunk/tinyNET/test/test_dns.h b/trunk/tinyNET/test/test_dns.h new file mode 100644 index 00000000..2668b290 --- /dev/null +++ b/trunk/tinyNET/test/test_dns.h @@ -0,0 +1,42 @@ +/* +* Copyright (C) 2009 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* 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 */ \ No newline at end of file diff --git a/trunk/vs_2005/tinyNET/test.vcproj b/trunk/vs_2005/tinyNET/test.vcproj index d4db5d38..b62c85f8 100644 --- a/trunk/vs_2005/tinyNET/test.vcproj +++ b/trunk/vs_2005/tinyNET/test.vcproj @@ -370,6 +370,10 @@ RelativePath="..\..\tinyNET\test\test_auth.h" > + + diff --git a/trunk/vs_2005/tinyNET/tinyNET.vcproj b/trunk/vs_2005/tinyNET/tinyNET.vcproj index b4202545..24ccf2ea 100644 --- a/trunk/vs_2005/tinyNET/tinyNET.vcproj +++ b/trunk/vs_2005/tinyNET/tinyNET.vcproj @@ -448,6 +448,10 @@ RelativePath="..\..\tinyNET\src\dns\tnet_dns_ns.c" > + + @@ -460,6 +464,10 @@ RelativePath="..\..\tinyNET\src\dns\tnet_dns_soa.c" > + + @@ -580,6 +588,10 @@ RelativePath="..\..\tinyNET\src\dns\tnet_dns_ns.h" > + +