recursiva. Se simplifica el cache porque sólo va a guardar registros de tipo A.
test_poll: test_poll.o libtcp.o
+#FIXME no va libtcp.o, debe ir sobre mi implementación de ip.
test_resolvprotos: test_resolvprotos.o libtcp.o ipaddr.o resolvproto.o
+#FIXME no va libtcp.o, debe ir sobre mi implementación de ip.
test_resolvprotoc: test_resolvprotoc.o libtcp.o ipaddr.o resolvproto.o
-test_nameserver_file: test_nameserver_file.o ipaddr.o nameserver.o
+#FIXME no va libtcp.o, debe ir sobre mi implementación de ip.
+test_nameserver_file: test_nameserver_file.o ipaddr.o nameserver.o \
+ resolvproto.o libtcp.o
-test_nameserver_resolvnext: test_nameserver_resolvnext.o ipaddr.o nameserver.o
+#FIXME no va libtcp.o, debe ir sobre mi implementación de ip.
+test_nameserver_resolvnext: test_nameserver_resolvnext.o ipaddr.o \
+ nameserver.o resolvproto.o libtcp.o
-ip: ip.o ipout.o ipin.o ipaddr.o ipheader.o devque.o devtcp.o routetable.o libtcp.o
+ip: ip.o ipout.o ipin.o ipaddr.o ipheader.o devque.o devtcp.o routetable.o \
+ libtcp.o
depend:
@makedepend $(fuentes) > /dev/null 2>&1
nameserver.o: nameserver.h ipaddr.h /usr/include/stdint.h
nameserver.o: /usr/include/features.h /usr/include/sys/cdefs.h
nameserver.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h
-nameserver.o: /usr/include/bits/wordsize.h
+nameserver.o: /usr/include/bits/wordsize.h resolvproto.h
resolvproto.o: resolvproto.h ipaddr.h /usr/include/stdint.h
resolvproto.o: /usr/include/features.h /usr/include/sys/cdefs.h
resolvproto.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h
test_nameserver_file.o: nameserver.h ipaddr.h /usr/include/stdint.h
test_nameserver_file.o: /usr/include/features.h /usr/include/sys/cdefs.h
test_nameserver_file.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h
-test_nameserver_file.o: /usr/include/bits/wordsize.h
+test_nameserver_file.o: /usr/include/bits/wordsize.h resolvproto.h
test_nameserver_resolvnext.o: nameserver.h ipaddr.h /usr/include/stdint.h
test_nameserver_resolvnext.o: /usr/include/features.h
test_nameserver_resolvnext.o: /usr/include/sys/cdefs.h
test_nameserver_resolvnext.o: /usr/include/gnu/stubs.h
test_nameserver_resolvnext.o: /usr/include/bits/wchar.h
-test_nameserver_resolvnext.o: /usr/include/bits/wordsize.h
+test_nameserver_resolvnext.o: /usr/include/bits/wordsize.h resolvproto.h
test_recv.o: devque.h dev.h /usr/include/unistd.h /usr/include/features.h
test_recv.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h
test_recv.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h
struct search_zone: std::unary_function< NameServer::Zone, bool >
{
bool local;
- NameServer::CacheRecord crecord;
+ ResolvProtoResponse resp;
const NameServer::Name& name;
search_zone(const NameServer::Name& n): local(false), name(n) {}
bool operator() (const NameServer::Zone& z)
if ((local_part.size() > 1) && r.type != NameServer::Record::NS)
continue;
found = true;
- crecord.ttl = z.ttl;
- crecord.records.push_back(r);
+ resp.ret = (r.type == NameServer::Record::NS)
+ ? ResolvProtoResponse::R_NS : ResolvProtoResponse::R_A;
+ resp.ttl = z.ttl;
+ resp.ips.push_back(r.ip);
}
}
return found;
}
};
-void NameServer::resolv_next(const Name& n)
+ResolvProtoResponse NameServer::resolv_next(const Name& n)
{
#ifdef DEBUG_RESOLV
std::cerr << "resolv_next -> tratando de resolver: " << n << "\n";
break;
if (found)
{
- // TODO mandar resultados?
#ifdef DEBUG_RESOLV
- std::cerr << "resolv_next found (local/hijo): " << zs.crecord << "\n";
+ std::cerr << "resolv_next found (local/hijo): " << zs.resp << "\n";
#endif
- return;
+ return zs.resp;
}
if (zs.local)
{
- // TODO mandar NOT FOUND
#ifdef DEBUG_RESOLV
std::cerr << "resolv_next NOT FOUND (es local pero no existe)\n";
#endif
- return;
+ return ResolvProtoResponse(ResolvProtoResponse::R_NOTFOUND);
}
cache_t::const_iterator i = cache.find(n);
// TODO TTL!?!
if (i != cache.end())
{
- // TODO mandar resultados?
#ifdef DEBUG_RESOLV
std::cerr << "resolv_next found (en cache): " << i->second << "\n";
#endif
- return;
+ const CacheRecord& cr = i->second;
+ return ResolvProtoResponse(ResolvProtoResponse::R_A, cr.ttl, cr.ips);
}
- // TODO enviar nameserver padre, si no hay padre, mandar NOT FOUND
if (zones.size())
{
#ifdef DEBUG_RESOLV
std::cerr << "resolv_next found (al padre): " << zones.front().parent
<< "\n";
- return;
+ ResolvProtoResponse rpr(ResolvProtoResponse::R_NS, zones.front().ttl);
+ rpr.ips.push_back(zones.front().parent);
+ return rpr;
#endif
}
- // TODO enviar NOT FOUND
#ifdef DEBUG_RESOLV
std::cerr << "resolv_next NOT FOUND (no hay padre)\n";
#endif
+ return ResolvProtoResponse(ResolvProtoResponse::R_NOTFOUND);
}
std::ostream& operator<< (std::ostream& os, const NameServer::Record::type_t& t)
std::ostream& operator<< (std::ostream& os, const NameServer::CacheRecord& cr)
{
os << "CacheRecord(ttl=" << cr.ttl << ", records=";
- std::copy(cr.records.begin(), cr.records.end(),
- std::ostream_iterator< NameServer::Record >(os, ","));
+ std::copy(cr.ips.begin(), cr.ips.end(),
+ std::ostream_iterator< IPAddr >(os, ","));
return os << ")";
}
#define _NAMESERVER_H_
#include "ipaddr.h"
-//XXX#include "resolvproto.h"
+#include "resolvproto.h"
#include <string>
#include <vector>
#include <map>
/// Time to live
size_t ttl;
/// Dirección IP del registro
- typedef std::vector< Record > records_t;
- records_t records;
+ typedef ResolvProtoResponse::ipvec_t ipvec_t;
+ ipvec_t ips;
/// Constructor
CacheRecord(): ttl(0) {}
- CacheRecord(size_t ttl, const records_t& records):
- ttl(ttl), records(records) {}
+ CacheRecord(size_t ttl, const ipvec_t& ips):
+ ttl(ttl), ips(ips) {}
};
/// Cache de records
NameServer(std::istream& is) throw (std::runtime_error);
/// Resuelve un nombre de forma no recursiva
- void resolv_next(const Name& n);
+ ResolvProtoResponse resolv_next(const Name& n);
};
/// Impresión (para debug)
<< ", name=" << rpr.name << ")";
}
+/// Constructor
+ResolvProtoResponse::ResolvProtoResponse(): ret(R_NOTFOUND), ttl(0)
+{
+}
+
/// Constructor
ResolvProtoResponse::ResolvProtoResponse(int fd)
{
}
/// Constructor
-ResolvProtoResponse::ResolvProtoResponse(ret_t ret, uint32_t ttl):
- ret(ret), ttl(ttl)
+ResolvProtoResponse::ResolvProtoResponse(ret_t ret, uint32_t ttl,
+ const ipvec_t& ips):
+ ret(ret), ttl(ttl), ips(ips)
{}
/// Envía por socket
/// Nombre a buscar
std::string name;
- /// Constructor
+ /// Constructores
ResolvProtoRequest(int fd);
-
- /// Constructor
ResolvProtoRequest(std::string name, uint8_t query_type = QT_RECURSIVE);
/// Envía por socket
typedef std::vector< IPAddr > ipvec_t;
ipvec_t ips;
- /// Constructor
+ /// Constructores
+ ResolvProtoResponse();
ResolvProtoResponse(int fd);
-
- /// Constructor
- ResolvProtoResponse(ret_t ret, uint32_t ttl);
+ ResolvProtoResponse(ret_t ret, uint32_t ttl = 0,
+ const ipvec_t& ips = ipvec_t());
/// Envía por socket
void send(int sockfd) const throw (std::runtime_error);
std::ifstream ifs("test_nameserver_zones.txt");
NameServer ns(ifs);
std::cout << ns << "\n";
- ns.resolv_next(N("tito.mi.super.nombre"));
- ns.resolv_next(N("juan.mi.super.nombre"));
- ns.resolv_next(N("pepe.otro.mi.super.nombre"));
- ns.resolv_next(N("pepe.mas.mi.super.nombre"));
- ns.resolv_next(N("super.nombre"));
- ns.resolv_next(N("nada.que.ver"));
+ std::cout << ns.resolv_next(N("tito.mi.super.nombre")) << "\n";
+ std::cout << ns.resolv_next(N("juan.mi.super.nombre")) << "\n";
+ std::cout << ns.resolv_next(N("pepe.otro.mi.super.nombre")) << "\n";
+ std::cout << ns.resolv_next(N("pepe.mas.mi.super.nombre")) << "\n";
+ std::cout << ns.resolv_next(N("super.nombre")) << "\n";
+ std::cout << ns.resolv_next(N("nada.que.ver")) << "\n";
+ std::cout << ns.resolv_next(N("tito.mas.super.nombres")) << "\n";
return 0;
}