#include "resolvproto.h"
-#include "libtcp.h"
#include <cstdlib>
#include <algorithm>
#include <iterator>
/// Constructor
-ResolvProtoRequest::ResolvProtoRequest(int fd)
+ResolvProtoRequest::ResolvProtoRequest(std::string name, uint8_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.c_str(), sizeof(uint8_t));
+ uint16_t size;
+ memcpy(&size, buf.c_str() + sizeof(uint8_t), sizeof(uint16_t));
+ name.assign(buf.c_str() + 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(R_NOTFOUND), ttl(0)
{
- recv(fd);
}
/// Constructor
-ResolvProtoResponse::ResolvProtoResponse(ret_t ret):
- ret(ret)
+ResolvProtoResponse::ResolvProtoResponse(std::string buf)
+{
+ memcpy(&ret, buf.c_str(), sizeof(uint8_t));
+ memcpy(&ttl, buf.c_str() + sizeof(uint8_t), sizeof(uint32_t));
+ uint8_t count;
+ memcpy(&count, buf.c_str() + 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.c_str() + 2 * sizeof(uint8_t)
+ + sizeof(uint32_t) * (i + 1), sizeof(uint32_t));
+ ips.push_back(ip);
+ }
+}
+
+/// Constructor
+ResolvProtoResponse::ResolvProtoResponse(ret_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 :