]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/resolvproto.cpp
Primera aproximación al cache y a la resolución de nombres.
[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 type):
15     type(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, &type, sizeof(uint8_t)) != sizeof(uint8_t))
23         throw std::runtime_error("Error al enviar 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, &type, sizeof(uint8_t)) != sizeof(uint8_t))
36         throw std::runtime_error("Error al recibir 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(type=" << unsigned(rpr.type) << ", name="
54         << rpr.name << ")";
55 }
56
57 /// Constructor
58 ResolvProtoResponse::ResolvProtoResponse(int fd)
59 {
60     recv(fd);
61 }
62
63 /// Constructor
64 ResolvProtoResponse::ResolvProtoResponse(ret_t ret):
65     ret(ret)
66 {}
67
68 /// Envía por socket
69 void ResolvProtoResponse::send(int sockfd) const
70     throw (std::runtime_error)
71 {
72     if (libtcp_send(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t))
73         throw std::runtime_error("Error al enviar ret por socket");
74     uint8_t count = ips.size();
75     if (libtcp_send(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t))
76         throw std::runtime_error("Error al enviar count por socket");
77     for (ipvec_t::const_iterator i = ips.begin(); i != ips.end(); ++i)
78     {
79         uint32_t ip = *i;
80         if (libtcp_send(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t))
81             throw std::runtime_error("Error al enviar IPAddr por socket");
82     }
83 }
84
85 /// Recibe por socket
86 void ResolvProtoResponse::recv(int sockfd)
87     throw (std::runtime_error)
88 {
89     if (libtcp_receive_bin(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t))
90         throw std::runtime_error("Error al recibir ret por socket");
91     uint8_t count;
92     if (libtcp_receive_bin(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t))
93         throw std::runtime_error("Error al recibir count por socket");
94     ips.clear();
95     ips.reserve(count);
96     for (uint8_t i = 0; i < count; ++i)
97     {
98         uint32_t ip;
99         if (libtcp_receive_bin(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t))
100             throw std::runtime_error("Error al recibir IPAddr por socket");
101         ips.push_back(ip);
102     }
103 }
104
105 /// Impresión de response
106 std::ostream& operator<< (std::ostream& os, const ResolvProtoResponse& rpr)
107 {
108     if (rpr.ips.empty())
109         return os;
110     os << "ResolvProtoResponse(ret=" << unsigned(rpr.ret) << ", ";
111     std::copy(rpr.ips.begin(), rpr.ips.end() - 1,
112             std::ostream_iterator< IPAddr >(os, ", "));
113     return os << rpr.ips.back() << ")";
114 }
115
116 // vim: set et sw=4 sts=4 :