From 61db0fa798876deeb90fc27f4ebdc207d3a53457 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Fri, 23 Jun 2006 18:33:36 +0000 Subject: [PATCH] =?utf8?q?Queda=20lo=20m=C3=ADnimo=20del=20DNS=20implement?= =?utf8?q?ado.=20Una=20prueba=20simple=20en=20una=20red=20sin=20routers=20?= =?utf8?q?anda=20bien=20(al=20menos=20andan=20varios=20queries=20a=20disti?= =?utf8?q?ntos=20servers=20con=20hasta=202=20niveles=20de=20indirecci?= =?utf8?q?=C3=B3n).=20Se=20agregan=20zonas=20de=20prueba=20para=20mi=20red?= =?utf8?q?=20interna.=20Quedan=20muchas=20cosas=20por=20resolver=20e=20imp?= =?utf8?q?lementar,=20pero=20lo=20b=C3=A1sico=20anda.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- practicas/pipi/rutas_ejemplo/mi_lan.txt | 4 + practicas/pipi/src/Makefile | 58 ++------ practicas/pipi/src/devque.cpp | 20 ++- practicas/pipi/src/devque.h | 11 +- practicas/pipi/src/dns.cpp | 128 +++++++++++++++++ practicas/pipi/src/ip.cpp | 4 +- practicas/pipi/src/nameserver.cpp | 134 +++++++++++++----- practicas/pipi/src/nameserver.h | 25 +++- practicas/pipi/src/resolvproto.cpp | 6 +- practicas/pipi/src/resolvproto.h | 33 ++--- practicas/pipi/src/test_nameserver_file.cpp | 4 +- .../pipi/src/test_nameserver_resolvnext.cpp | 4 +- practicas/pipi/src/test_resolvproto.cpp | 4 +- practicas/pipi/zonas_ejemplo/10.10.10.1.txt | 27 ++++ practicas/pipi/zonas_ejemplo/10.10.10.141.txt | 16 +++ practicas/pipi/zonas_ejemplo/10.10.10.2.txt | 12 ++ practicas/pipi/zonas_ejemplo/10.10.10.3.txt | 28 ++++ 17 files changed, 400 insertions(+), 118 deletions(-) create mode 100644 practicas/pipi/rutas_ejemplo/mi_lan.txt create mode 100644 practicas/pipi/src/dns.cpp create mode 100644 practicas/pipi/zonas_ejemplo/10.10.10.1.txt create mode 100644 practicas/pipi/zonas_ejemplo/10.10.10.141.txt create mode 100644 practicas/pipi/zonas_ejemplo/10.10.10.2.txt create mode 100644 practicas/pipi/zonas_ejemplo/10.10.10.3.txt diff --git a/practicas/pipi/rutas_ejemplo/mi_lan.txt b/practicas/pipi/rutas_ejemplo/mi_lan.txt new file mode 100644 index 0000000..aa77b5c --- /dev/null +++ b/practicas/pipi/rutas_ejemplo/mi_lan.txt @@ -0,0 +1,4 @@ +10.10.10.1 0.0.0.0 30 0 +10.10.10.2 0.0.0.0 30 0 +10.10.10.3 0.0.0.0 30 0 +10.10.10.141 0.0.0.0 30 0 diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile index f76f0e2..d116c96 100644 --- a/practicas/pipi/src/Makefile +++ b/practicas/pipi/src/Makefile @@ -30,7 +30,7 @@ CXXFLAGS = $(CFLAGS) -fno-inline CC=g++ # Programas -targets=ip +targets=ip dns tests=test_send test_recv test_ipaddr test_ipin test_ipout test_devtcp \ test_poll test_resolvproto test_nameserver_file \ test_nameserver_resolvnext @@ -74,6 +74,8 @@ test_nameserver_resolvnext: test_nameserver_resolvnext.o $(dns_objs) $(ip_objs) ip: ip.o $(ip_objs) +dns: dns.o $(ip_objs) $(dns_objs) + depend: @makedepend $(fuentes) > /dev/null 2>&1 @@ -138,10 +140,11 @@ dns.o: ipout.h ipaddr.h /usr/include/stdint.h /usr/include/features.h dns.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h dns.o: /usr/include/bits/wchar.h /usr/include/bits/wordsize.h ipheader.h dns.o: routetable.h dev.h ipin.h devtcp.h /usr/include/sys/poll.h -dns.o: /usr/include/bits/poll.h devque.h /usr/include/unistd.h -dns.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h -dns.o: /usr/include/bits/typesizes.h /usr/include/bits/confname.h -dns.o: /usr/include/getopt.h /usr/include/fcntl.h /usr/include/bits/fcntl.h +dns.o: /usr/include/bits/poll.h devque.h nameserver.h resolvproto.h +dns.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +dns.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h +dns.o: /usr/include/bits/confname.h /usr/include/getopt.h +dns.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h dns.o: /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h dns.o: /usr/include/bits/endian.h /usr/include/sys/select.h dns.o: /usr/include/bits/select.h /usr/include/bits/sigset.h @@ -348,51 +351,6 @@ test_resolvproto.o: /usr/include/asm-i486/sockios.h /usr/include/netinet/in.h test_resolvproto.o: /usr/include/bits/in.h /usr/include/bits/byteswap.h test_resolvproto.o: /usr/include/arpa/inet.h /usr/include/netdb.h test_resolvproto.o: /usr/include/rpc/netdb.h /usr/include/bits/netdb.h -test_resolvprotoc.o: resolvproto.h ipaddr.h /usr/include/stdint.h -test_resolvprotoc.o: /usr/include/features.h /usr/include/sys/cdefs.h -test_resolvprotoc.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h -test_resolvprotoc.o: /usr/include/bits/wordsize.h ipin.h ipheader.h dev.h -test_resolvprotoc.o: ipout.h routetable.h libtcp.h /usr/include/stdio.h -test_resolvprotoc.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h -test_resolvprotoc.o: /usr/include/libio.h /usr/include/_G_config.h -test_resolvprotoc.o: /usr/include/wchar.h /usr/include/gconv.h -test_resolvprotoc.o: /usr/include/bits/stdio_lim.h -test_resolvprotoc.o: /usr/include/bits/sys_errlist.h /usr/include/stdlib.h -test_resolvprotoc.o: /usr/include/sys/types.h /usr/include/time.h -test_resolvprotoc.o: /usr/include/endian.h /usr/include/bits/endian.h -test_resolvprotoc.o: /usr/include/sys/select.h /usr/include/bits/select.h -test_resolvprotoc.o: /usr/include/bits/sigset.h /usr/include/bits/time.h -test_resolvprotoc.o: /usr/include/sys/sysmacros.h -test_resolvprotoc.o: /usr/include/bits/pthreadtypes.h -test_resolvprotoc.o: /usr/include/bits/sched.h /usr/include/alloca.h -test_resolvprotoc.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h -test_resolvprotoc.o: /usr/include/bits/confname.h /usr/include/getopt.h -test_resolvprotoc.o: /usr/include/signal.h /usr/include/bits/signum.h -test_resolvprotoc.o: /usr/include/bits/siginfo.h -test_resolvprotoc.o: /usr/include/bits/sigaction.h -test_resolvprotoc.o: /usr/include/bits/sigcontext.h -test_resolvprotoc.o: /usr/include/asm/sigcontext.h -test_resolvprotoc.o: /usr/include/asm-i486/sigcontext.h -test_resolvprotoc.o: /usr/include/linux/compiler.h -test_resolvprotoc.o: /usr/include/bits/sigstack.h -test_resolvprotoc.o: /usr/include/bits/sigthread.h /usr/include/sys/wait.h -test_resolvprotoc.o: /usr/include/sys/resource.h /usr/include/bits/resource.h -test_resolvprotoc.o: /usr/include/bits/waitflags.h -test_resolvprotoc.o: /usr/include/bits/waitstatus.h /usr/include/string.h -test_resolvprotoc.o: /usr/include/sys/socket.h /usr/include/sys/uio.h -test_resolvprotoc.o: /usr/include/bits/uio.h /usr/include/bits/socket.h -test_resolvprotoc.o: /usr/include/limits.h /usr/include/bits/posix1_lim.h -test_resolvprotoc.o: /usr/include/bits/local_lim.h -test_resolvprotoc.o: /usr/include/linux/limits.h -test_resolvprotoc.o: /usr/include/bits/posix2_lim.h -test_resolvprotoc.o: /usr/include/bits/sockaddr.h /usr/include/asm/socket.h -test_resolvprotoc.o: /usr/include/asm-i486/socket.h -test_resolvprotoc.o: /usr/include/asm/sockios.h -test_resolvprotoc.o: /usr/include/asm-i486/sockios.h -test_resolvprotoc.o: /usr/include/netinet/in.h /usr/include/bits/in.h -test_resolvprotoc.o: /usr/include/bits/byteswap.h /usr/include/arpa/inet.h -test_resolvprotoc.o: /usr/include/netdb.h /usr/include/rpc/netdb.h -test_resolvprotoc.o: /usr/include/bits/netdb.h test_send.o: devque.h dev.h /usr/include/unistd.h /usr/include/features.h test_send.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h test_send.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h diff --git a/practicas/pipi/src/devque.cpp b/practicas/pipi/src/devque.cpp index fd54398..0791354 100644 --- a/practicas/pipi/src/devque.cpp +++ b/practicas/pipi/src/devque.cpp @@ -20,7 +20,7 @@ DevQue::DevQue(mac_type mac, key_t key, size_t mtu) throw (std::runtime_error, std::logic_error): Dev(mac, mtu) { - que_id = msgget(key, 0666); // Debe estar previamente creada + que_id = msgget(key, IPC_CREAT | 0666); if (que_id == -1) throw std::runtime_error("No se pudo crear la cola"); } @@ -51,7 +51,7 @@ std::string DevQue::receive() throw (std::runtime_error) return receive(mac); } -std::string DevQue::receive(const mac_type& mac) throw (std::runtime_error) +std::string DevQue::receive(mac_type& mac) throw (std::runtime_error) { Frame* f = (Frame*) malloc(sizeof(Frame) + mtu); if (!f) @@ -63,6 +63,8 @@ std::string DevQue::receive(const mac_type& mac) throw (std::runtime_error) throw std::runtime_error("Error al sacar de la cola"); } std::string s((char*) f->frame, f->size); + if (mac == 0) + mac = f->mac; free(f); #ifdef DEBUG2 std::cout << "DevQue::receive(msgtype/mac = " << mac << ", size = " @@ -71,4 +73,18 @@ std::string DevQue::receive(const mac_type& mac) throw (std::runtime_error) return s; } +/// Indica cuantos elementos hay en la cola +size_t DevQue::size() const +{ + struct msqid_ds minfo; + msgctl(que_id, IPC_STAT, &minfo); + return minfo.msg_qnum; +} + +/// Indica si está vacía la cola +bool DevQue::empty() const +{ + return size() == 0; +} + // vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/devque.h b/practicas/pipi/src/devque.h index 603d7bd..70ddb36 100644 --- a/practicas/pipi/src/devque.h +++ b/practicas/pipi/src/devque.h @@ -24,9 +24,18 @@ struct DevQue: Dev /// Recibe un frame std::string receive() throw (std::runtime_error); - std::string receive(const mac_type& mac) + + /// Recibe un frame para el tipo de mac especificado, si es 0 recibe + /// cualquier y guarda en esa mac la dirección. + std::string receive(mac_type& mac) throw (std::runtime_error); + /// Indica cuantos elementos hay en la cola + size_t size() const; + + /// Indica si está vacía la cola + bool empty() const; + }; #endif // _DEVQUE_H_ diff --git a/practicas/pipi/src/dns.cpp b/practicas/pipi/src/dns.cpp new file mode 100644 index 0000000..5b3c66c --- /dev/null +++ b/practicas/pipi/src/dns.cpp @@ -0,0 +1,128 @@ + +#include "ipout.h" +#include "ipin.h" +#include "ipaddr.h" +#include "routetable.h" +#include "devtcp.h" +#include "devque.h" +#include "nameserver.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Uso: ./dns ip [routes_file zones_file forward port] + +void send_loop(NameServer& ns); + +void add_routes(RouteTable& rt, std::istream& is, Dev& dev); + +int main(int argc, char* argv[]) +{ + uint16_t port = DEVTCP_DEFAULT_PORT; + std::string rfile = "route.txt"; + std::string zfile = "zones.txt"; + if (argc < 2) + { + std::cerr << "Uso: " << argv[0] << " ip [route_file zone_file port]\n"; + return 1; + } + IPAddr addr(argv[1]); + if (argc > 2) + rfile = argv[2]; + if (argc > 3) + zfile = argv[3]; + if (argc > 4) + port = atoi(argv[4]); + // Abro archivo con rutas + std::ifstream rifs(rfile.c_str()); assert(rifs); + // Abro archivo con zonas + std::ifstream zifs(zfile.c_str()); assert(zifs); + // Creo medio físico y colas para forwarding y NameServer + DevTCP dev(addr, port); + DevQue fwque(addr, DEVQUE_DEFAULT_KEY-1); + DevQue nsreqque(addr, DEVQUE_DEFAULT_KEY-2); + DevQue nsresque(addr, DEVQUE_DEFAULT_KEY-3); + DevQue nssndque(addr, DEVQUE_DEFAULT_KEY-4); + // Creo Rutas, IPOut, IPIn + RouteTable table(dev); + add_routes(table, rifs, dev); + IPOut ipout(addr, table, fwque, std::cerr); + IPIn ipin(addr, dev, fwque, false, false, std::cerr); + NameServer ns(zifs, ipin, ipout, nsreqque, nsresque, nssndque); + // Creo procesos + pid_t pid_send = fork(); + if (pid_send == -1) + { + perror("fork() send"); + return 2; + } + if (pid_send) // IPOut + { + pid_t pid_fw = fork(); + if (pid_fw == -1) + { + perror("fork() forward"); + return 3; + } + if (pid_fw) // Padre (Entrada por teclado) + { + int ret; + send_loop(ns); + kill(pid_send, SIGTERM); + waitpid(pid_send, &ret, 0); + kill(pid_fw, SIGTERM); + waitpid(pid_fw, &ret, 0); + return 0; + } + else // Hijo 1 (envío del DNS) + { + ns.send_loop(); + return 0; + } + } + else // Hijo 2 (recepción del DNS) + { + ns.recv_loop(); + return 0; + } + return 0; +} + +void send_loop(NameServer& ns) +{ + std::string name; + while (std::getline(std::cin, name)) + { + std::cout << "Resolviendo " << name << "...\n"; + ResolvProtoResponse res = ns.resolv_recursive(name); + std::cout << "Resultado: " << res << "\n"; + } +} + +void add_routes(RouteTable& rt, std::istream& is, Dev& dev) +{ + std::string line; + while (std::getline(is, line)) + { + std::istringstream iss(line); + std::string net; + std::string gw; + unsigned mtu; + unsigned metric; + iss >> net >> gw >> mtu >> metric; + if (net == "0") net = "0.0.0.0"; + if (gw == "0") gw = "0.0.0.0"; + rt.add(net, gw, metric, mtu, dev); + } +} + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/ip.cpp b/practicas/pipi/src/ip.cpp index 6bffcfd..6988169 100644 --- a/practicas/pipi/src/ip.cpp +++ b/practicas/pipi/src/ip.cpp @@ -18,7 +18,7 @@ #include #include -// Uso: ./test_ipout ip [router forward routes_file port proto] +// Uso: ./ip ip [router forward routes_file port proto] void send_loop(IPOut& ipout, unsigned proto); @@ -33,7 +33,7 @@ int main(int argc, char* argv[]) std::string fname = "route.txt"; if (argc < 2) { - std::cerr << "Uso: ./test_ipout ip [router forward routes_file " + std::cerr << "Uso: " << argv[0] << " ip [router forward routes_file " "port proto]\n"; return 1; } diff --git a/practicas/pipi/src/nameserver.cpp b/practicas/pipi/src/nameserver.cpp index cf7dac3..86f18e8 100644 --- a/practicas/pipi/src/nameserver.cpp +++ b/practicas/pipi/src/nameserver.cpp @@ -27,7 +27,7 @@ std::ostream& operator<< (std::ostream& os, const NameServer::Name& name) return os << name.back(); } -NameServer::Name::operator std::string () +NameServer::Name::operator std::string () const { std::stringstream ss; ss << *this; @@ -96,8 +96,11 @@ void NameServer::Zone::clear() } /// Constructor -NameServer::NameServer(std::istream& is) - throw (std::runtime_error) +NameServer::NameServer(std::istream& is, IPIn& ipin, IPOut& ipout, + DevQue& req_que, DevQue& res_que, DevQue& snd_que) + throw (std::runtime_error): + ipin(ipin), ipout(ipout), req_que(req_que), res_que(res_que), + snd_que(snd_que) { Zone z; while (parsezone(is, z)) @@ -201,8 +204,8 @@ struct search_zone: std::unary_function< NameServer::Zone, bool > if ((local_part.size() > 1) && r.type != NameServer::Record::NS) continue; found = true; - resp.ret = (r.type == NameServer::Record::NS) - ? ResolvProtoResponse::R_NS : ResolvProtoResponse::R_A; + resp.ret = (r.type == NameServer::Record::NS) ? RP_RES_NS + : RP_RES_A; resp.ttl = z.ttl; resp.ips.push_back(r.ip); } @@ -234,7 +237,7 @@ ResolvProtoResponse NameServer::resolv_direct(const Name& n) #ifdef DEBUG_RESOLV std::cerr << "resolv_direct NOT FOUND (es local pero no existe)\n"; #endif - return ResolvProtoResponse(ResolvProtoResponse::R_NOTFOUND); + return ResolvProtoResponse(RP_RES_NOTFOUND); } cache_t::const_iterator i = cache.find(n); // TODO TTL!?! @@ -244,7 +247,7 @@ ResolvProtoResponse NameServer::resolv_direct(const Name& n) std::cerr << "resolv_direct found (en cache): " << i->second << "\n"; #endif const CacheRecord& cr = i->second; - return ResolvProtoResponse(ResolvProtoResponse::R_A, cr.ttl, cr.ips); + return ResolvProtoResponse(RP_RES_A, cr.ttl, cr.ips); } if (zones.size()) { @@ -261,7 +264,7 @@ ResolvProtoResponse NameServer::resolv_direct(const Name& n) std::cerr << "resolv_direct found (al padre): " << i->parent << "\n"; #endif - ResolvProtoResponse rpr(ResolvProtoResponse::R_NS, i->ttl); + ResolvProtoResponse rpr(RP_RES_NS, i->ttl); rpr.ips.push_back(i->parent); return rpr; } @@ -271,7 +274,7 @@ ResolvProtoResponse NameServer::resolv_direct(const Name& n) std::cerr << "resolv_direct NOT FOUND (no hay padre)\n"; #endif // No hay padre, no puedo hacer nada más - return ResolvProtoResponse(ResolvProtoResponse::R_NOTFOUND); + return ResolvProtoResponse(RP_RES_NOTFOUND); } /// Resuelve un nombre de forma recursiva @@ -280,12 +283,12 @@ ResolvProtoResponse NameServer::resolv_recursive(const Name& n) ResolvProtoResponse rpr = resolv_direct(n); switch (rpr.ret) { - case ResolvProtoResponse::R_NS: + case RP_RES_NS: #ifdef DEBUG_RESOLV std::cerr << "resolv_recursive -> redirect a " << rpr << "\n"; #endif return resolv_recursive_r(n, rpr); // Sigo "bajando" - case ResolvProtoResponse::R_A: + case RP_RES_A: #ifdef DEBUG_RESOLV std::cerr << "resolv_recursive -> gotcha! " << rpr << "\n"; #endif @@ -306,18 +309,18 @@ ResolvProtoResponse NameServer::resolv_recursive_r(const Name& n, r = query(n, *ip); switch (r.ret) { - case ResolvProtoResponse::R_NS: + case RP_RES_NS: #ifdef DEBUG_RESOLV std::cerr << "resolv_recursive_r -> redirect a " << r << "\n"; #endif return resolv_recursive_r(n, r); // Sigo "bajando" - case ResolvProtoResponse::R_NOTFOUND: + case RP_RES_NOTFOUND: #ifdef DEBUG_RESOLV std::cerr << "resolv_recursive_r -> NOT FOUND en " << *ip << ", sigo probando\n"; #endif break; // Sigo probando del mismo nivel - case ResolvProtoResponse::R_A: + case RP_RES_A: #ifdef DEBUG_RESOLV std::cerr << "resolv_recursive_r -> gotcha! " << r << "\n"; #endif @@ -334,33 +337,92 @@ ResolvProtoResponse NameServer::resolv_recursive_r(const Name& n, /// Consulta a otro name server sobre un nombre ResolvProtoResponse NameServer::query(const Name& n, const IPAddr& ip) { - // TODO IMPLEMENTAR!!! + ResolvProtoRequest r(std::string(n), RP_REQ_DIRECT); #ifdef DEBUG_RESOLV - std::cerr << "query -> Haciendo query dummy\n"; + std::cerr << "query -> pidiendo " << r << " a " << ip << "\n"; #endif - if (ip == IPAddr("10.10.10.1")) - { - ResolvProtoResponse r(ResolvProtoResponse::R_NS, 500); - r.ips.push_back(IPAddr("10.10.10.2")); - r.ips.push_back(IPAddr("10.10.10.3")); - return r; - } - else if (ip == IPAddr("10.10.10.2")) - { - return ResolvProtoResponse(ResolvProtoResponse::R_NOTFOUND); - } - else if (ip == IPAddr("10.10.10.3")) + // Envía a través de la cola de envío + snd_que.transmit(std::string(r), ip); + Dev::mac_type mac = ip; + std::string buf = res_que.receive(mac); + ResolvProtoResponse resp(buf); +#ifdef DEBUG_RESOLV + std::cerr << "query -> recibido " << resp << " de " << ip << "\n"; +#endif + return resp; +} + +void NameServer::recv_loop() +{ + while (true) { - ResolvProtoResponse r(ResolvProtoResponse::R_NS, 666); - r.ips.push_back(IPAddr("10.10.10.4")); - return r; + IPAddr src, dst; + uint8_t proto; + std::string s = ipin.recv(proto, src, dst); +#ifdef DEBUG_RESOLV + std::cout << "NameServer::recv_loop() -> recibido len=" << s.size() + << " de " << src << " para " << dst << " (proto = " + << unsigned(proto) << ")\n"; +#endif + if (proto == NAMESERVER_PROTO) // Si es para nosotros + { + rp_pkt_type_t type; + memcpy(&type, s.c_str(), sizeof(uint8_t)); + switch (type) + { + // Request + case RP_REQ_DIRECT: + case RP_REQ_RECURSIVE: +#ifdef DEBUG_RESOLV + std::cout << "---> " << ResolvProtoRequest(s) << "\n"; +#endif + req_que.transmit(s, src); // Encolo + break; + // Response + default: +#ifdef DEBUG_RESOLV + std::cout << "---> " << ResolvProtoResponse(s) << "\n"; +#endif + res_que.transmit(s, src); // Encolo + } + } } - else +} + +void NameServer::send_loop() +{ + while (true) { - ResolvProtoResponse r(ResolvProtoResponse::R_A, 1500); - r.ips.push_back(IPAddr("10.10.10.5")); - r.ips.push_back(IPAddr("10.10.10.6")); - return r; + if (!req_que.empty()) + { + Dev::mac_type mac = 0; + ResolvProtoRequest req(req_que.receive(mac)); +#ifdef DEBUG_RESOLV + std::cout << "NameServer::send_loop() -> recibido " << req << "\n"; +#endif + ResolvProtoResponse res + = (req.query_type == RP_REQ_DIRECT) + ? resolv_direct(req.name) + : resolv_recursive(req.name); +#ifdef DEBUG_RESOLV + std::cout << "NameServer::send_loop() -> respondo " << res << "\n"; +#endif + ipout.send(res, NAMESERVER_PROTO, IPAddr(mac)); + } + else if (!snd_que.empty()) // Hay un request para enviar + { + Dev::mac_type mac = 0; + std::string buf = snd_que.receive(mac); +#ifdef DEBUG_RESOLV + std::cout << "NameServer::send_loop() -> envío request " + << ResolvProtoRequest(buf) << "\n"; +#endif + ipout.send(buf, NAMESERVER_PROTO, IPAddr(mac)); + } + else // No hay nada, esperamos un rato + { + usleep(10000); + } } } diff --git a/practicas/pipi/src/nameserver.h b/practicas/pipi/src/nameserver.h index dbaecf7..d9b8a4f 100644 --- a/practicas/pipi/src/nameserver.h +++ b/practicas/pipi/src/nameserver.h @@ -1,6 +1,7 @@ #ifndef _NAMESERVER_H_ #define _NAMESERVER_H_ +#include "devque.h" #include "ipaddr.h" #include "resolvproto.h" #include @@ -10,6 +11,8 @@ #include #include +#define NAMESERVER_PROTO 59 + /// Petición del resolver a un nameserver struct NameServer { @@ -20,7 +23,7 @@ struct NameServer /// Constructor Name() {} Name(const std::string& name); - operator std::string (); + operator std::string () const; }; /// Registro de una zona @@ -77,8 +80,20 @@ struct NameServer typedef std::map< Name, CacheRecord > cache_t; cache_t cache; + /// IP + IPIn& ipin; + IPOut& ipout; + + /// Colas de recepción + DevQue& req_que; // De requests + DevQue& res_que; // De responses + + /// Cola de envío + DevQue& snd_que; + /// Constructor - NameServer(std::istream& is) throw (std::runtime_error); + NameServer(std::istream& is, IPIn& ipin, IPOut& ipout, DevQue& req_que, + DevQue& res_que, DevQue& snd_que) throw (std::runtime_error); /// Resuelve un nombre de forma directa (no recursiva) ResolvProtoResponse resolv_direct(const Name& n); @@ -89,6 +104,12 @@ struct NameServer /// Consulta a otro name server sobre un nombre ResolvProtoResponse query(const Name&n, const IPAddr& ip); + /// Loop que recibe y carga los paquetes en las colas para ser procesados + void recv_loop(); + + /// Loop que envía los paquetes de la cola de envío + void send_loop(); + private: /// Resuelve un nombre de forma recursiva entrando a otros ns ResolvProtoResponse resolv_recursive_r(const Name& n, diff --git a/practicas/pipi/src/resolvproto.cpp b/practicas/pipi/src/resolvproto.cpp index 55e960c..f55bbf2 100644 --- a/practicas/pipi/src/resolvproto.cpp +++ b/practicas/pipi/src/resolvproto.cpp @@ -4,7 +4,7 @@ #include /// Constructor -ResolvProtoRequest::ResolvProtoRequest(std::string name, uint8_t query_type): +ResolvProtoRequest::ResolvProtoRequest(std::string name, rp_pkt_type_t query_type): query_type(query_type), name(name) {} @@ -40,7 +40,7 @@ std::ostream& operator<< (std::ostream& os, const ResolvProtoRequest& rpr) } /// Constructor -ResolvProtoResponse::ResolvProtoResponse(): ret(R_NOTFOUND), ttl(0) +ResolvProtoResponse::ResolvProtoResponse(): ret(RP_RES_NOTFOUND), ttl(0) { } @@ -63,7 +63,7 @@ ResolvProtoResponse::ResolvProtoResponse(std::string buf) } /// Constructor -ResolvProtoResponse::ResolvProtoResponse(ret_t ret, uint32_t ttl, +ResolvProtoResponse::ResolvProtoResponse(rp_pkt_type_t ret, uint32_t ttl, const ipvec_t& ips): ret(ret), ttl(ttl), ips(ips) {} diff --git a/practicas/pipi/src/resolvproto.h b/practicas/pipi/src/resolvproto.h index 50ec171..2100771 100644 --- a/practicas/pipi/src/resolvproto.h +++ b/practicas/pipi/src/resolvproto.h @@ -9,6 +9,19 @@ #include #include +/// Tipo de petición +enum rp_pkt_type_t +{ + // requests + RP_REQ_DIRECT, ///> Búsqueda directa (inter nameservers) + RP_REQ_RECURSIVE, ///> Búsqueda recursiva (para resolvers) + // responses + RP_RES_A, ///> OK, se devolvió un registro A + RP_RES_NS, ///> OK, se devolvió un registro NS (sólo en directo) + RP_RES_NOTFOUND, ///> No se encontró + RP_RES_TIMEOUT ///> Tardó demasiado la consulta +}; + /// Petición de un nameserver /// +------------+------------+------------+ /// | QUERY_TYPE | SIZE | NAME | @@ -17,19 +30,14 @@ struct ResolvProtoRequest { - /// Tipo de petición - enum query_type_t - { - QT_DIRECT, ///> Búsqueda directa (inter nameservers) - QT_RECURSIVE ///> Búsqueda recursiva (para resolvers) - }; + /// Tipo de petición (de tipo rp_pkt_type_t) uint8_t query_type; /// Nombre a buscar std::string name; /// Constructores - ResolvProtoRequest(std::string name, uint8_t query_type); + ResolvProtoRequest(std::string name, rp_pkt_type_t query_type); ResolvProtoRequest(std::string buf); /// Envía por socket @@ -58,14 +66,7 @@ std::ostream& operator<< (std::ostream& os, const ResolvProtoRequest& rpr); struct ResolvProtoResponse { - /// Resultado de la respuesta - enum ret_t - { - R_A, ///> OK, se devolvió un registro A - R_NS, ///> OK, se devolvió un registro NS (sólo en directo) - R_NOTFOUND, ///> No se encontró - R_TIMEOUT ///> Tardó demasiado la consulta - }; + /// Resultado de la respuesta (de tipo rp_pkt_type_t) uint8_t ret; /// TTL (sólo útil para búsquedas (inter nameserver) @@ -77,7 +78,7 @@ struct ResolvProtoResponse /// Constructores ResolvProtoResponse(); - ResolvProtoResponse(ret_t ret, uint32_t ttl = 0, + ResolvProtoResponse(rp_pkt_type_t ret, uint32_t ttl = 0, const ipvec_t& ips = ipvec_t()); ResolvProtoResponse(std::string buf); diff --git a/practicas/pipi/src/test_nameserver_file.cpp b/practicas/pipi/src/test_nameserver_file.cpp index 43a4215..b6f158d 100644 --- a/practicas/pipi/src/test_nameserver_file.cpp +++ b/practicas/pipi/src/test_nameserver_file.cpp @@ -8,8 +8,8 @@ int main(int argc, char* argv[]) { std::ifstream ifs("test_nameserver_zones.txt"); - NameServer ns(ifs); - std::cout << ns << "\n"; + //FIXME NameServer ns(ifs); + //FIXME std::cout << ns << "\n"; return 0; } diff --git a/practicas/pipi/src/test_nameserver_resolvnext.cpp b/practicas/pipi/src/test_nameserver_resolvnext.cpp index 2c62274..1ebf385 100644 --- a/practicas/pipi/src/test_nameserver_resolvnext.cpp +++ b/practicas/pipi/src/test_nameserver_resolvnext.cpp @@ -9,7 +9,7 @@ int main(int argc, char* argv[]) { typedef NameServer::Name N; std::ifstream ifs("test_nameserver_zones.txt"); - NameServer ns(ifs); + /* XXX NameServer ns(ifs); std::cout << ns << "\n"; std::cout << ns.resolv_direct(N("tito.mi.super.nombre")) << "\n"; std::cout << ns.resolv_direct(N("juan.mi.super.nombre")) << "\n"; @@ -18,7 +18,7 @@ int main(int argc, char* argv[]) std::cout << ns.resolv_direct(N("super.nombre")) << "\n"; std::cout << ns.resolv_direct(N("nada.que.ver")) << "\n"; std::cout << ns.resolv_direct(N("tito.mas.super.nombres")) << "\n"; - std::cout << ns.resolv_recursive(N("nada.que.ver")) << "\n"; + std::cout << ns.resolv_recursive(N("nada.que.ver")) << "\n";*/ return 0; } diff --git a/practicas/pipi/src/test_resolvproto.cpp b/practicas/pipi/src/test_resolvproto.cpp index ba1c136..964240b 100644 --- a/practicas/pipi/src/test_resolvproto.cpp +++ b/practicas/pipi/src/test_resolvproto.cpp @@ -6,11 +6,11 @@ int main() { - ResolvProtoRequest req("hola.tito", ResolvProtoRequest::QT_RECURSIVE); + ResolvProtoRequest req("hola.tito", RP_REQ_RECURSIVE); std::cout << "Request Original: " << req << "\n"; ResolvProtoRequest req2 = std::string(req); std::cout << "Request Reconstruido: " << req2 << "\n"; - ResolvProtoResponse res(ResolvProtoResponse::R_A, 600); + ResolvProtoResponse res(RP_RES_A, 600); res.ips.push_back(IPAddr("10.10.10.2")); res.ips.push_back(IPAddr("100.20.45.21")); res.ips.push_back(IPAddr("230.23.62.189")); diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.1.txt b/practicas/pipi/zonas_ejemplo/10.10.10.1.txt new file mode 100644 index 0000000..5381f9d --- /dev/null +++ b/practicas/pipi/zonas_ejemplo/10.10.10.1.txt @@ -0,0 +1,27 @@ +casa 600 0.0.0.0 +burns A 10.10.10.1 +homero A 10.10.10.2 +marge A 10.10.10.3 +manuk A 10.10.10.141 +juan A 100.10.100.5 +pepe A 100.10.100.6 +homero NS 10.10.10.2 +marge NS 10.10.10.3 +manuk NS 10.10.10.141 + +burns.casa 600 0.0.0.0 +tito A 100.10.100.1 +juan A 100.10.100.2 +juan A 100.10.100.3 +pepe A 100.10.100.4 +juan A 100.10.100.5 +pepe A 100.10.100.6 + +todos.homero.casa 9500 0.0.0.0 +tito A 10.1.100.1 +juan A 10.1.100.2 +juan A 10.1.100.3 +pepe A 10.1.100.4 +juan A 10.1.100.5 +pepe A 10.1.100.6 + diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.141.txt b/practicas/pipi/zonas_ejemplo/10.10.10.141.txt new file mode 100644 index 0000000..d75a5d8 --- /dev/null +++ b/practicas/pipi/zonas_ejemplo/10.10.10.141.txt @@ -0,0 +1,16 @@ +manuk.marge.casa 600 10.10.10.3 +tito A 40.10.100.1 +juan A 40.10.100.2 +juan A 40.10.100.3 +pepe A 40.10.100.4 +juan A 40.10.100.5 +pepe A 40.10.100.6 + +todos.homero.casa 9500 10.10.10.2 +tito A 10.1.100.1 +juan A 10.1.100.2 +juan A 10.1.100.3 +pepe A 10.1.100.4 +juan A 10.1.100.5 +pepe A 10.1.100.6 + diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.2.txt b/practicas/pipi/zonas_ejemplo/10.10.10.2.txt new file mode 100644 index 0000000..4cd1503 --- /dev/null +++ b/practicas/pipi/zonas_ejemplo/10.10.10.2.txt @@ -0,0 +1,12 @@ +homero.casa 600 10.10.10.1 +tito A 10.10.100.1 +juan A 10.10.100.2 +juan A 10.10.100.3 +pepe A 10.10.100.4 +juan A 10.10.100.5 +pepe A 10.10.100.6 +marge NS 10.10.10.3 +todos NS 10.10.10.1 +todos NS 10.10.10.3 +todos NS 10.10.10.141 + diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.3.txt b/practicas/pipi/zonas_ejemplo/10.10.10.3.txt new file mode 100644 index 0000000..dc45182 --- /dev/null +++ b/practicas/pipi/zonas_ejemplo/10.10.10.3.txt @@ -0,0 +1,28 @@ +marge.casa 600 10.10.10.1 +tito A 30.10.100.1 +juan A 30.10.100.2 +juan A 30.10.100.3 +pepe A 30.10.100.4 +juan A 30.10.100.5 +pepe A 30.10.100.6 +manuk NS 10.10.10.141 +todos NS 10.10.10.1 +todos NS 10.10.10.3 +todos NS 10.10.10.141 + +todos.homero.casa 9500 10.10.10.2 +tito A 10.1.100.1 +juan A 10.1.100.2 +juan A 10.1.100.3 +pepe A 10.1.100.4 +juan A 10.1.100.5 +pepe A 10.1.100.6 + +marge.homero.casa 9500 10.10.10.2 +tito A 10.3.100.1 +juan A 10.3.100.2 +juan A 10.3.100.3 +pepe A 10.3.100.4 +juan A 10.3.100.5 +pepe A 10.3.100.6 + -- 2.43.0