]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/ip.cpp
Cosas de Distribuidos I.
[z.facultad/75.74/practicos.git] / practicas / pipi / src / ip.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 <iostream>
9 #include <fstream>
10 #include <sstream>
11 #include <string>
12 #include <cassert>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
17 #include <sys/ipc.h>
18 #include <sys/msg.h>
19 #include <signal.h>
20
21 // Uso: ./ip ip [router forward routes_file port proto]
22
23 void send_loop(IPOut& ipout, unsigned proto);
24
25 int main(int argc, char* argv[])
26 {
27     bool router = false;
28     bool forward = false;
29     uint8_t proto = 0;
30     uint16_t port = DEVTCP_DEFAULT_PORT;
31     std::string fname = "route.txt";
32     if (argc < 2)
33     {
34         std::cerr << "Uso: " << argv[0] << " ip [router forward routes_file "
35             "port proto]\n";
36         return 1;
37     }
38     IPAddr addr(argv[1]);
39     if (argc > 2)
40         router = atoi(argv[2]);
41     if (argc > 3)
42         forward = atoi(argv[3]);
43     if (argc > 4)
44         fname = argv[4];
45     if (argc > 5)
46         port = atoi(argv[5]);
47     if (argc > 6)
48         proto = atoi(argv[6]);
49     // Abro archivo con rutas
50     std::ifstream ifs(fname.c_str()); assert(ifs);
51     // Creo medio físico y cola para forwarding
52     DevTCP dev(addr, port);
53     DevQue fwque(addr, DEVQUE_DEFAULT_KEY-1);
54     // Creo procesos
55     pid_t pid_send = fork();
56     if (pid_send == -1)
57     {
58         perror("fork() send");
59         return 2;
60     }
61     if (pid_send) // IPOut
62     {
63         RouteTable table(dev);
64         add_routes(table, ifs, dev);
65         IPOut ipout(addr, table, fwque, std::cerr);
66         pid_t pid_fw = fork();
67         if (pid_fw == -1)
68         {
69             perror("fork() forward");
70             return 3;
71         }
72         if (pid_fw) // Padre (IPOut send)
73         {
74             int ret;
75             send_loop(ipout, proto);
76             kill(pid_send, SIGTERM);
77             waitpid(pid_send, &ret, 0);
78             kill(pid_fw, SIGTERM);
79             waitpid(pid_fw, &ret, 0);
80             return 0;
81         }
82         else // Hijo 1 (IPOut forward)
83         {
84             ipout.forward_loop();
85             return 0;
86         }
87     }
88     else // Hijo 2 (IPIn)
89     {
90         IPIn ipin(addr, dev, fwque, router, forward, std::cerr);
91         while (true)
92         {
93             IPAddr src, dst;
94             std::string s = ipin.recv(proto, src, dst);
95             std::cout << "Recibido '" << s << "' (len " << s.size() << ") de "
96                 << src << " para " << dst << " (proto = " << unsigned(proto)
97                 << ")\n";
98         }
99         return 0;
100     }
101     return 0;
102 }
103
104 void send_loop(IPOut& ipout, unsigned proto)
105 {
106     std::string dst;
107     std::string msg;
108     while (std::getline(std::cin, dst))
109     {
110         if (!std::getline(std::cin, msg))
111             break;
112         if (ipout.send(msg, proto, IPAddr(dst.c_str())))
113             std::cout << "Enviado '" << msg << "' a " << dst << "\n";
114         else
115             std::cout << "NO SE PUDO ENVIAR '" << msg << "' a " << dst << "\n";
116     }
117 }
118
119 // vim: set et sw=4 sts=4 :