]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
Queda lo mínimo del DNS implementado. Una prueba simple en una red sin routers
authorLeandro Lucarella <llucax@gmail.com>
Fri, 23 Jun 2006 18:33:36 +0000 (18:33 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 23 Jun 2006 18:33:36 +0000 (18:33 +0000)
anda bien (al menos andan varios queries a distintos servers con hasta 2 niveles
de indirección). Se agregan zonas de prueba para mi red interna. Quedan muchas
cosas por resolver e implementar, pero lo básico anda.

17 files changed:
practicas/pipi/rutas_ejemplo/mi_lan.txt [new file with mode: 0644]
practicas/pipi/src/Makefile
practicas/pipi/src/devque.cpp
practicas/pipi/src/devque.h
practicas/pipi/src/dns.cpp [new file with mode: 0644]
practicas/pipi/src/ip.cpp
practicas/pipi/src/nameserver.cpp
practicas/pipi/src/nameserver.h
practicas/pipi/src/resolvproto.cpp
practicas/pipi/src/resolvproto.h
practicas/pipi/src/test_nameserver_file.cpp
practicas/pipi/src/test_nameserver_resolvnext.cpp
practicas/pipi/src/test_resolvproto.cpp
practicas/pipi/zonas_ejemplo/10.10.10.1.txt [new file with mode: 0644]
practicas/pipi/zonas_ejemplo/10.10.10.141.txt [new file with mode: 0644]
practicas/pipi/zonas_ejemplo/10.10.10.2.txt [new file with mode: 0644]
practicas/pipi/zonas_ejemplo/10.10.10.3.txt [new file with mode: 0644]

diff --git a/practicas/pipi/rutas_ejemplo/mi_lan.txt b/practicas/pipi/rutas_ejemplo/mi_lan.txt
new file mode 100644 (file)
index 0000000..aa77b5c
--- /dev/null
@@ -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
index f76f0e2053039a5035b5d75b22a49e088740df38..d116c962aa9827ed8ab4112cb032ffae47a0d4f0 100644 (file)
@@ -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
index fd5439865d63169e39af185b972bd4683bb3ad01..07913548f9eff59f063c73b9f677def3a5791d42 100644 (file)
@@ -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 :
index 603d7bd8b3f05777ea54e74489a4bcffe91d7718..70ddb36d2b9001853ea03b866075de9a96189103 100644 (file)
@@ -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 (file)
index 0000000..5b3c66c
--- /dev/null
@@ -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 <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <cassert>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <signal.h>
+
+// 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 :
index 6bffcfdbbb29718db2e5bfed85e2eec668d339ca..6988169c01d2200c92318a763a2b5dd2f1e2040f 100644 (file)
@@ -18,7 +18,7 @@
 #include <sys/msg.h>
 #include <signal.h>
 
-// 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;
     }
index cf7dac33208141847e82138977b0f5d2902c326c..86f18e8556117e3926eeb6d1a751d4c3ff938a68 100644 (file)
@@ -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);
+        }
     }
 }
 
index dbaecf74217658585c3be27d8a8ac41f19ef4a49..d9b8a4f3419faa76129c89e6462c2b2b9fe5c581 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _NAMESERVER_H_
 #define _NAMESERVER_H_
 
+#include "devque.h"
 #include "ipaddr.h"
 #include "resolvproto.h"
 #include <string>
@@ -10,6 +11,8 @@
 #include <ostream>
 #include <stdexcept>
 
+#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,
index 55e960c570375c925ed82e92852eebcc1209a6ca..f55bbf20d70dacf795e2fb93e8da9794e5478ef5 100644 (file)
@@ -4,7 +4,7 @@
 #include <iterator>
 
 /// 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)
 {}
index 50ec1719c10db88215f68079a5a51a772b41efd0..210077117e408f6648d074ddd2628af12548c375 100644 (file)
@@ -9,6 +9,19 @@
 #include <stdexcept>
 #include <stdint.h>
 
+/// 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    |
 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);
 
index 43a421524e2f814b1ca3d987071fb95a6601d0a8..b6f158d7343f15f0a3883fef8611a511224bba18 100644 (file)
@@ -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;
 }
 
index 2c6227404ec7cdb9435c88792c323f89c651efa3..1ebf3852326c7a76087b15f55b904dcd2403afe2 100644 (file)
@@ -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;
 }
 
index ba1c13694bda568d71a81fabfb65ab1a38d379b9..964240bf14d90f7832d4e7e16d746fea3ad65c58 100644 (file)
@@ -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 (file)
index 0000000..5381f9d
--- /dev/null
@@ -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 (file)
index 0000000..d75a5d8
--- /dev/null
@@ -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 (file)
index 0000000..4cd1503
--- /dev/null
@@ -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 (file)
index 0000000..dc45182
--- /dev/null
@@ -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
+