QByteArray Common::packAddress(const Address &addr)//pack a shadowsocks header { QByteArray ss_header; QByteArray address_str = addr.getAddress().toLocal8Bit(); QByteArray address_bin; quint16 port_net = htons(addr.getPort()); QByteArray port_ns = QByteArray::fromRawData(reinterpret_cast<char *>(&port_net), 2); int type = addr.addressType(); ss_header.append(static_cast<char>(type)); switch (type) { case Address::ADDRTYPE_HOST://should we care if it exceeds 255? ss_header.append(static_cast<char>(address_str.length())); ss_header += address_str; break; case Address::ADDRTYPE_IPV4: address_bin.resize(INET_ADDRSTRLEN); inet_pton(AF_INET, address_str.constData(), reinterpret_cast<void *>(address_bin.data())); ss_header += address_bin; break; case Address::ADDRTYPE_IPV6: address_bin.resize(INET6_ADDRSTRLEN); inet_pton(AF_INET6, address_str.constData(), reinterpret_cast<void *>(address_bin.data())); ss_header += address_bin; break; } return ss_header + port_ns; }
//pack a shadowsocks header std::string Common::packAddress(const Address &addr) { std::string portNs(2, '\0'); qToBigEndian(addr.getPort(), reinterpret_cast<uchar*>(&portNs[0])); std::string addrBin; const Address::ATYP type = addr.addressType(); if (type == Address::HOST) { const std::string& addressString = addr.getAddress(); //can't be longer than 255 addrBin = static_cast<char>(addressString.length()) + addressString; } else if (type == Address::IPV4) { uint32_t ipv4Address = qToBigEndian(addr.getFirstIP().toIPv4Address()); addrBin = std::string(reinterpret_cast<char*>(&ipv4Address), 4); } else { //Q_IPV6ADDR is a 16-unsigned-char struct (big endian) Q_IPV6ADDR ipv6Address = addr.getFirstIP().toIPv6Address(); addrBin = std::string(reinterpret_cast<char*>(ipv6Address.c), 16); } char typeChar = static_cast<char>(type); return typeChar + addrBin + portNs; }