summaryrefslogtreecommitdiff
path: root/node/InetAddress.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/InetAddress.hpp')
-rw-r--r--node/InetAddress.hpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp
index 3c05d83b..c376a032 100644
--- a/node/InetAddress.hpp
+++ b/node/InetAddress.hpp
@@ -38,6 +38,7 @@
#include "../include/ZeroTierOne.h"
#include "Utils.hpp"
#include "MAC.hpp"
+#include "Buffer.hpp"
namespace ZeroTier {
@@ -362,6 +363,51 @@ struct InetAddress : public sockaddr_storage
*/
inline operator bool() const throw() { return (ss_family != 0); }
+ template<unsigned int C>
+ inline void serialize(Buffer<C> &b) const
+ {
+ // Format is the same as in VERB_HELLO in Packet.hpp
+ switch(ss_family) {
+ case AF_INET:
+ b.append((uint8_t)0x04);
+ b.append(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr),4);
+ b.append((uint16_t)port()); // just in case sin_port != uint16_t
+ return;
+ case AF_INET6:
+ b.append((uint8_t)0x06);
+ b.append(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,16);
+ b.append((uint16_t)port()); // just in case sin_port != uint16_t
+ return;
+ default:
+ b.append((uint8_t)0);
+ return;
+ }
+ }
+
+ template<unsigned int C>
+ inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
+ {
+ unsigned int p = startAt;
+ memset(this,0,sizeof(InetAddress));
+ switch(b[p++]) {
+ case 0:
+ return 1;
+ case 0x04:
+ ss_family = AF_INET;
+ memcpy(&(reinterpret_cast<struct sockaddr_in *>(this)->sin_addr.s_addr),b.field(p,4),4); p += 4;
+ reinterpret_cast<struct sockaddr_in *>(this)->sin_port = Utils::hton(b.template at<uint16_t>(p)); p += 2;
+ break;
+ case 0x06:
+ ss_family = AF_INET6;
+ memcpy(reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,b.field(p,16),16); p += 16;
+ reinterpret_cast<struct sockaddr_in *>(this)->sin_port = Utils::hton(b.template at<uint16_t>(p)); p += 2;
+ break;
+ default:
+ throw std::invalid_argument("invalid serialized InetAddress");
+ }
+ return (p - startAt);
+ }
+
bool operator==(const InetAddress &a) const throw();
bool operator<(const InetAddress &a) const throw();
inline bool operator!=(const InetAddress &a) const throw() { return !(*this == a); }