#include "proxy.hpp"
#include <iostream>
#include <iomanip>
using namespace boost;
ScionUDPAddr parseProxyHeader(const char* buffer, size_t len)
{
ScionUDPAddr addr;
if (len < PROXY_HEADER_LEN) {
throw std::runtime_error("Invalid unix socket packet header");
}
for (size_t i = 0; i < 2; ++i)
addr.isd[i] = buffer[i];
for (size_t i = 0; i < 6; ++i)
addr.asn[i] = buffer[2 + i];
uint32_t addrLen = *(uint32_t*)&buffer[8];
if (addrLen == 4) {
asio::ip::address_v4::bytes_type bytes;
std::copy_n(buffer + 12, 4, bytes.begin());
addr.ip = asio::ip::address_v4(bytes);
} else if (addrLen == 16) {
asio::ip::address_v6::bytes_type bytes;
std::copy_n(buffer + 12, 16, bytes.begin());
addr.ip = asio::ip::address_v6(bytes);
} else {
throw std::runtime_error("Invalid unix socket packet header");
}
addr.port = *(uint16_t*)&buffer[28];
return addr;
}
std::ostream& operator<<(std::ostream& stream, const ScionUDPAddr& addr)
{
stream << std::dec << ((uint32_t)addr.isd[1] | ((uint32_t)addr.isd[0]) << 8) << '-';
stream << std::hex << std::setfill('0');
stream.width(2);
stream << +addr.asn[0] << +addr.asn[1] << ':';
stream << +addr.asn[2] << +addr.asn[3] << ':';
stream << +addr.asn[4] << +addr.asn[5] << ',';
stream.width(0);
if (addr.ip.is_v6()) stream << '[';
stream << addr.ip;
if (addr.ip.is_v6()) stream << ']';
stream << ':' << std::dec << addr.port;
return stream;
}