]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/dns.cpp
5b3c66c00244f9adda844a28ff22c10efd5131b2
[z.facultad/75.74/practicos.git] / practicas / pipi / src / dns.cpp
1
2 #include "ipout.h"
3 #include "ipin.h"
4 #include "ipaddr.h"
5 #include "routetable.h"
6 #include "devtcp.h"
7 #include "devque.h"
8 #include "nameserver.h"
9 #include <iostream>
10 #include <fstream>
11 #include <sstream>
12 #include <string>
13 #include <cassert>
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <sys/types.h>
17 #include <sys/wait.h>
18 #include <sys/ipc.h>
19 #include <sys/msg.h>
20 #include <signal.h>
21
22 // Uso: ./dns ip [routes_file zones_file forward port]
23
24 void send_loop(NameServer& ns);
25
26 void add_routes(RouteTable& rt, std::istream& is, Dev& dev);
27
28 int main(int argc, char* argv[])
29 {
30     uint16_t port = DEVTCP_DEFAULT_PORT;
31     std::string rfile = "route.txt";
32     std::string zfile = "zones.txt";
33     if (argc < 2)
34     {
35         std::cerr << "Uso: " << argv[0] << " ip [route_file zone_file port]\n";
36         return 1;
37     }
38     IPAddr addr(argv[1]);
39     if (argc > 2)
40         rfile = argv[2];
41     if (argc > 3)
42         zfile = argv[3];
43     if (argc > 4)
44         port = atoi(argv[4]);
45     // Abro archivo con rutas
46     std::ifstream rifs(rfile.c_str()); assert(rifs);
47     // Abro archivo con zonas
48     std::ifstream zifs(zfile.c_str()); assert(zifs);
49     // Creo medio físico y colas para forwarding y NameServer
50     DevTCP dev(addr, port);
51     DevQue fwque(addr, DEVQUE_DEFAULT_KEY-1);
52     DevQue nsreqque(addr, DEVQUE_DEFAULT_KEY-2);
53     DevQue nsresque(addr, DEVQUE_DEFAULT_KEY-3);
54     DevQue nssndque(addr, DEVQUE_DEFAULT_KEY-4);
55     // Creo Rutas, IPOut, IPIn
56     RouteTable table(dev);
57     add_routes(table, rifs, dev);
58     IPOut ipout(addr, table, fwque, std::cerr);
59     IPIn ipin(addr, dev, fwque, false, false, std::cerr);
60     NameServer ns(zifs, ipin, ipout, nsreqque, nsresque, nssndque);
61     // Creo procesos
62     pid_t pid_send = fork();
63     if (pid_send == -1)
64     {
65         perror("fork() send");
66         return 2;
67     }
68     if (pid_send) // IPOut
69     {
70         pid_t pid_fw = fork();
71         if (pid_fw == -1)
72         {
73             perror("fork() forward");
74             return 3;
75         }
76         if (pid_fw) // Padre (Entrada por teclado)
77         {
78             int ret;
79             send_loop(ns);
80             kill(pid_send, SIGTERM);
81             waitpid(pid_send, &ret, 0);
82             kill(pid_fw, SIGTERM);
83             waitpid(pid_fw, &ret, 0);
84             return 0;
85         }
86         else // Hijo 1 (envío del DNS)
87         {
88             ns.send_loop();
89             return 0;
90         }
91     }
92     else // Hijo 2 (recepción del DNS)
93     {
94         ns.recv_loop();
95         return 0;
96     }
97     return 0;
98 }
99
100 void send_loop(NameServer& ns)
101 {
102     std::string name;
103     while (std::getline(std::cin, name))
104     {
105         std::cout << "Resolviendo " << name << "...\n";
106         ResolvProtoResponse res = ns.resolv_recursive(name);
107         std::cout << "Resultado: " << res << "\n";
108     }
109 }
110
111 void add_routes(RouteTable& rt, std::istream& is, Dev& dev)
112 {
113     std::string line;
114     while (std::getline(is, line))
115     {
116         std::istringstream iss(line);
117         std::string net;
118         std::string gw;
119         unsigned mtu;
120         unsigned metric;
121         iss >> net >> gw >> mtu >> metric;
122         if (net == "0") net = "0.0.0.0";
123         if (gw == "0") gw = "0.0.0.0";
124         rt.add(net, gw, metric, mtu, dev);
125     }
126 }
127
128 // vim: set et sw=4 sts=4 :