]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/resolvproto.cpp
Se agrega opción para recibir paquetes de un host específico y se mejora el
[z.facultad/75.74/practicos.git] / practicas / pipi / src / resolvproto.cpp
1 #include "resolvproto.h"
2 #include "libtcp.h"
3 #include <cstdlib>
4 #include <algorithm>
5 #include <iterator>
6
7 /// Constructor
8 ResolvProtoRequest::ResolvProtoRequest(int fd)
9 {
10     recv(fd);
11 }
12
13 /// Constructor
14 ResolvProtoRequest::ResolvProtoRequest(std::string name, uint8_t query_type):
15     query_type(query_type), name(name)
16 {}
17
18 /// Envía por socket
19 void ResolvProtoRequest::send(int sockfd) const
20     throw (std::runtime_error)
21 {
22     if (libtcp_send(sockfd, &query_type, sizeof(uint8_t)) != sizeof(uint8_t))
23         throw std::runtime_error("Error al enviar query_type por socket");
24     uint16_t size = name.size();
25     if (libtcp_send(sockfd, &size, sizeof(uint16_t)) != sizeof(uint16_t))
26         throw std::runtime_error("Error al enviar size por socket");
27     if (libtcp_send(sockfd, name.c_str(), size) != size)
28         throw std::runtime_error("Error al enviar name por socket");
29 }
30
31 /// Recibe por socket
32 void ResolvProtoRequest::recv(int sockfd)
33     throw (std::runtime_error)
34 {
35     if (libtcp_receive_bin(sockfd, &query_type, sizeof(uint8_t)) != sizeof(uint8_t))
36         throw std::runtime_error("Error al recibir query_type por socket");
37     uint16_t size;
38     if (libtcp_receive_bin(sockfd, &size, sizeof(uint16_t)) != sizeof(uint16_t))
39         throw std::runtime_error("Error al recibir size por socket");
40     char* buf = (char*) malloc(size);
41     if (libtcp_receive_bin(sockfd, buf, size) != size)
42     {
43         free(buf);
44         throw std::runtime_error("Error al recibir name por socket");
45     }
46     name.assign(buf, size);
47     free(buf);
48 }
49
50 /// Impresión de request
51 std::ostream& operator<< (std::ostream& os, const ResolvProtoRequest& rpr)
52 {
53     return os << "ResolvProtoRequest(query_type=" << unsigned(rpr.query_type)
54         << ", name=" << rpr.name << ")";
55 }
56
57 /// Constructor
58 ResolvProtoResponse::ResolvProtoResponse(): ret(R_NOTFOUND), ttl(0)
59 {
60 }
61
62 /// Constructor
63 ResolvProtoResponse::ResolvProtoResponse(int fd)
64 {
65     recv(fd);
66 }
67
68 /// Constructor
69 ResolvProtoResponse::ResolvProtoResponse(ret_t ret, uint32_t ttl,
70         const ipvec_t& ips):
71     ret(ret), ttl(ttl), ips(ips)
72 {}
73
74 /// Envía por socket
75 void ResolvProtoResponse::send(int sockfd) const
76     throw (std::runtime_error)
77 {
78     if (libtcp_send(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t))
79         throw std::runtime_error("Error al enviar ret por socket");
80     if (libtcp_send(sockfd, &ttl, sizeof(uint32_t)) != sizeof(uint32_t))
81         throw std::runtime_error("Error al enviar ttl por socket");
82     uint8_t count = ips.size();
83     if (libtcp_send(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t))
84         throw std::runtime_error("Error al enviar count por socket");
85     for (ipvec_t::const_iterator i = ips.begin(); i != ips.end(); ++i)
86     {
87         uint32_t ip = *i;
88         if (libtcp_send(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t))
89             throw std::runtime_error("Error al enviar IPAddr por socket");
90     }
91 }
92
93 /// Recibe por socket
94 void ResolvProtoResponse::recv(int sockfd)
95     throw (std::runtime_error)
96 {
97     if (libtcp_receive_bin(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t))
98         throw std::runtime_error("Error al recibir ret por socket");
99     if (libtcp_receive_bin(sockfd, &ttl, sizeof(uint32_t)) != sizeof(uint32_t))
100         throw std::runtime_error("Error al recibir ttl por socket");
101     uint8_t count;
102     if (libtcp_receive_bin(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t))
103         throw std::runtime_error("Error al recibir count por socket");
104     ips.clear();
105     ips.reserve(count);
106     for (uint8_t i = 0; i < count; ++i)
107     {
108         uint32_t ip;
109         if (libtcp_receive_bin(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t))
110             throw std::runtime_error("Error al recibir IPAddr por socket");
111         ips.push_back(ip);
112     }
113 }
114
115 /// Impresión de response
116 std::ostream& operator<< (std::ostream& os, const ResolvProtoResponse& rpr)
117 {
118     os << "ResolvProtoResponse(ret=" << unsigned(rpr.ret)
119         << ", ttl=" << rpr.ttl;
120     if (rpr.ips.empty())
121         return os << ")";
122     os << ", ";
123     std::copy(rpr.ips.begin(), rpr.ips.end() - 1,
124             std::ostream_iterator< IPAddr >(os, ", "));
125     return os << rpr.ips.back() << ")";
126 }
127
128 // vim: set et sw=4 sts=4 :