X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/blobdiff_plain/037c7a6a269f053f09e3ebab3c28e4453b576d18..91fb3ca6b56328c626dabb35e2de9a5ae525b1b1:/practicas/pipi/src/resolvproto.cpp?ds=sidebyside diff --git a/practicas/pipi/src/resolvproto.cpp b/practicas/pipi/src/resolvproto.cpp index 92a5512..3b39419 100644 --- a/practicas/pipi/src/resolvproto.cpp +++ b/practicas/pipi/src/resolvproto.cpp @@ -1,114 +1,104 @@ #include "resolvproto.h" -#include "libtcp.h" #include #include #include /// Constructor -ResolvProtoRequest::ResolvProtoRequest(int fd) +ResolvProtoRequest::ResolvProtoRequest(std::string name, rp_pkt_type_t query_type): + query_type(query_type), name(name) +{} + +/// Constructor a partir de un buffer +ResolvProtoRequest::ResolvProtoRequest(std::string buf) { - recv(fd); + memcpy(&query_type, buf.data(), sizeof(uint8_t)); + uint16_t size; + memcpy(&size, buf.data() + sizeof(uint8_t), sizeof(uint16_t)); + name.assign(buf.data() + sizeof(uint8_t) + sizeof(uint16_t), size); } -/// Constructor -ResolvProtoRequest::ResolvProtoRequest(std::string name, uint8_t type): - type(type), name(name) -{} - -/// Envía por socket -void ResolvProtoRequest::send(int sockfd) const - throw (std::runtime_error) +/// Convierte a un buffer +ResolvProtoRequest::operator std::string () const { - if (libtcp_send(sockfd, &type, sizeof(uint8_t)) != sizeof(uint8_t)) - throw std::runtime_error("Error al enviar type por socket"); + std::string buf((char*)&query_type, sizeof(uint8_t)); uint16_t size = name.size(); - if (libtcp_send(sockfd, &size, sizeof(uint16_t)) != sizeof(uint16_t)) - throw std::runtime_error("Error al enviar size por socket"); - if (libtcp_send(sockfd, name.c_str(), size) != size) - throw std::runtime_error("Error al enviar name por socket"); + buf.append((char*)&size, sizeof(uint16_t)); + buf.append(name); + return buf; } -/// Recibe por socket -void ResolvProtoRequest::recv(int sockfd) - throw (std::runtime_error) +size_t ResolvProtoRequest::packet_size() const { - if (libtcp_receive_bin(sockfd, &type, sizeof(uint8_t)) != sizeof(uint8_t)) - throw std::runtime_error("Error al recibir type por socket"); - uint16_t size; - if (libtcp_receive_bin(sockfd, &size, sizeof(uint16_t)) != sizeof(uint16_t)) - throw std::runtime_error("Error al recibir size por socket"); - char* buf = (char*) malloc(size); - if (libtcp_receive_bin(sockfd, buf, size) != size) - { - free(buf); - throw std::runtime_error("Error al recibir name por socket"); - } - name.assign(buf, size); - free(buf); + return sizeof(uint8_t) + sizeof(uint16_t) + name.size(); } /// Impresión de request std::ostream& operator<< (std::ostream& os, const ResolvProtoRequest& rpr) { - return os << "ResolvProtoRequest(type=" << unsigned(rpr.type) << ", name=" - << rpr.name << ")"; + return os << "ResolvProtoRequest(query_type=" << unsigned(rpr.query_type) + << ", name=" << rpr.name << ")"; } /// Constructor -ResolvProtoResponse::ResolvProtoResponse(int fd) +ResolvProtoResponse::ResolvProtoResponse(): ret(RP_RES_NOTFOUND), ttl(0) { - recv(fd); } /// Constructor -ResolvProtoResponse::ResolvProtoResponse(ret_t ret): - ret(ret) +ResolvProtoResponse::ResolvProtoResponse(std::string buf) +{ + memcpy(&ret, buf.data(), sizeof(uint8_t)); + memcpy(&ttl, buf.data() + sizeof(uint8_t), sizeof(uint32_t)); + uint8_t count; + memcpy(&count, buf.data() + sizeof(uint8_t) + sizeof(uint32_t), + sizeof(uint8_t)); + ips.reserve(count); + for (uint8_t i = 0; i < count; ++i) + { + uint32_t ip; + memcpy(&ip, buf.data() + 2 * sizeof(uint8_t) + + sizeof(uint32_t) * (i + 1), sizeof(uint32_t)); + ips.push_back(ip); + } +} + +/// Constructor +ResolvProtoResponse::ResolvProtoResponse(rp_pkt_type_t ret, uint32_t ttl, + const ipvec_t& ips): + ret(ret), ttl(ttl), ips(ips) {} -/// Envía por socket -void ResolvProtoResponse::send(int sockfd) const - throw (std::runtime_error) +/// Convierte a buffer +ResolvProtoResponse::operator std::string () const { - if (libtcp_send(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t)) - throw std::runtime_error("Error al enviar ret por socket"); + std::string buf((char*)&ret, sizeof(uint8_t)); + buf.append((char*)&ttl, sizeof(uint32_t)); uint8_t count = ips.size(); - if (libtcp_send(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t)) - throw std::runtime_error("Error al enviar count por socket"); + buf.append((char*)&count, sizeof(uint8_t)); for (ipvec_t::const_iterator i = ips.begin(); i != ips.end(); ++i) { uint32_t ip = *i; - if (libtcp_send(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t)) - throw std::runtime_error("Error al enviar IPAddr por socket"); + buf.append((char*)&ip, sizeof(uint32_t)); } + return buf; } -/// Recibe por socket -void ResolvProtoResponse::recv(int sockfd) - throw (std::runtime_error) +size_t ResolvProtoResponse::packet_size() const { - if (libtcp_receive_bin(sockfd, &ret, sizeof(uint8_t)) != sizeof(uint8_t)) - throw std::runtime_error("Error al recibir ret por socket"); - uint8_t count; - if (libtcp_send(sockfd, &count, sizeof(uint8_t)) != sizeof(uint8_t)) - throw std::runtime_error("Error al recibir count por socket"); - ips.clear(); - ips.reserve(count); - for (uint8_t i = 0; i < count; ++i) - { - uint32_t ip; - if (libtcp_send(sockfd, &ip, sizeof(uint32_t)) != sizeof(uint32_t)) - throw std::runtime_error("Error al recibir IPAddr por socket"); - ips.push_back(ip); - } + return 2 * sizeof(uint8_t) + (ips.size() + 1) * sizeof(uint32_t); } /// Impresión de response std::ostream& operator<< (std::ostream& os, const ResolvProtoResponse& rpr) { - os << "ResolvProtoResponse(ret=" << unsigned(rpr.ret) << ", "; - std::copy(rpr.ips.begin(), rpr.ips.end(), + os << "ResolvProtoResponse(ret=" << unsigned(rpr.ret) + << ", ttl=" << rpr.ttl; + if (rpr.ips.empty()) + return os << ")"; + os << ", "; + std::copy(rpr.ips.begin(), rpr.ips.end() - 1, std::ostream_iterator< IPAddr >(os, ", ")); - return os << ")"; + return os << rpr.ips.back() << ")"; } // vim: set et sw=4 sts=4 :