summaryrefslogtreecommitdiff
path: root/node/Peer.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Peer.hpp')
-rw-r--r--node/Peer.hpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/node/Peer.hpp b/node/Peer.hpp
index 568de0d5..482c0a82 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -445,6 +445,127 @@ public:
else return std::pair<InetAddress,InetAddress>();
}
+ template<unsigned int C>
+ inline void serialize(Buffer<C> &b) const
+ {
+ Mutex::Lock _l(_lock);
+
+ const unsigned int lengthAt = b.size();
+ b.addSize(4); // space for uint32_t field length
+
+ b.append((uint32_t)1); // version of serialized Peer data
+
+ _id.serialize(b,false);
+
+ b.append((uint64_t)_lastUsed);
+ b.append((uint64_t)_lastReceive);
+ b.append((uint64_t)_lastUnicastFrame);
+ b.append((uint64_t)_lastMulticastFrame);
+ b.append((uint64_t)_lastAnnouncedTo);
+ b.append((uint64_t)_lastPathConfirmationSent);
+ b.append((uint64_t)_lastDirectPathPush);
+ b.append((uint64_t)_lastPathSort);
+ b.append((uint16_t)_vProto);
+ b.append((uint16_t)_vMajor);
+ b.append((uint16_t)_vMinor);
+ b.append((uint16_t)_vRevision);
+ b.append((uint32_t)_latency);
+
+ b.append((uint32_t)_numPaths);
+ for(unsigned int i=0;i<_numPaths;++i)
+ _paths[i].serialize(b);
+
+ b.append((uint32_t)_networkComs.size());
+ {
+ uint64_t *k = (uint64_t *)0;
+ _NetworkCom *v = (_NetworkCom *)0;
+ Hashtable<uint64_t,_NetworkCom>::Iterator i(const_cast<Peer *>(this)->_networkComs);
+ while (i.next(k,v)) {
+ b.append((uint64_t)*k);
+ b.append((uint64_t)v->ts);
+ v->com.serialize(b);
+ }
+ }
+
+ b.append((uint32_t)_lastPushedComs.size());
+ {
+ uint64_t *k = (uint64_t *)0;
+ uint64_t *v = (uint64_t *)0;
+ Hashtable<uint64_t,uint64_t>::Iterator i(const_cast<Peer *>(this)->_lastPushedComs);
+ while (i.next(k,v)) {
+ b.append((uint64_t)*k);
+ b.append((uint64_t)*v);
+ }
+ }
+
+ b.setAt(lengthAt,(uint32_t)((b.size() - 4) - lengthAt)); // set size, not including size field itself
+ }
+
+ /**
+ * Create a new Peer from a serialized instance
+ *
+ * @param myIdentity This node's identity
+ * @param b Buffer containing serialized Peer data
+ * @param p Pointer to current position in buffer, will be updated in place as buffer is read (value/result)
+ * @return New instance of Peer or NULL if serialized data was corrupt or otherwise invalid (may also throw an exception via Buffer)
+ */
+ template<unsigned int C>
+ static inline SharedPtr<Peer> deserializeNew(const Identity &myIdentity,const Buffer<C> &b,unsigned int &p)
+ {
+ const uint32_t recSize = b.template at<uint32_t>(p); p += 4;
+ if ((p + recSize) > b.size())
+ return SharedPtr<Peer>(); // size invalid
+ if (b.template at<uint32_t>(p) != 1)
+ return SharedPtr<Peer>(); // version mismatch
+ p += 4;
+
+ Identity npid;
+ p += npid.deserialize(b,p);
+ if (!npid)
+ return SharedPtr<Peer>();
+
+ SharedPtr<Peer> np(new Peer(myIdentity,npid));
+
+ np->_lastUsed = b.template at<uint64_t>(p); p += 8;
+ np->_lastReceive = b.template at<uint64_t>(p); p += 8;
+ np->_lastUnicastFrame = b.template at<uint64_t>(p); p += 8;
+ np->_lastMulticastFrame = b.template at<uint64_t>(p); p += 8;
+ np->_lastAnnouncedTo = b.template at<uint64_t>(p); p += 8;
+ np->_lastPathConfirmationSent = b.template at<uint64_t>(p); p += 8;
+ np->_lastDirectPathPush = b.template at<uint64_t>(p); p += 8;
+ np->_lastPathSort = b.template at<uint64_t>(p); p += 8;
+ np->_vProto = b.template at<uint16_t>(p); p += 2;
+ np->_vMajor = b.template at<uint16_t>(p); p += 2;
+ np->_vMinor = b.template at<uint16_t>(p); p += 2;
+ np->_vRevision = b.template at<uint16_t>(p); p += 2;
+ np->_latency = b.template at<uint32_t>(p); p += 4;
+
+ const unsigned int numPaths = b.template at<uint32_t>(p); p += 2;
+ for(unsigned int i=0;i<numPaths;++i) {
+ if (i < ZT_MAX_PEER_NETWORK_PATHS) {
+ p += np->_paths[np->_numPaths++].deserialize(b,p);
+ } else {
+ // Skip any paths beyond max, but still read stream
+ RemotePath foo;
+ p += foo.deserialize(b,p);
+ }
+ }
+
+ const unsigned int numNetworkComs = b.template at<uint32_t>(p); p += 4;
+ for(unsigned int i=0;i<numNetworkComs;++i) {
+ _NetworkCom &c = np->_networkComs[b.template at<uint64_t>(p)]; p += 8;
+ c.ts = b.template at<uint64_t>(p); p += 8;
+ p += c.com.deserialize(b,p);
+ }
+
+ const unsigned int numLastPushed = b.template at<uint32_t>(p); p += 4;
+ for(unsigned int i=0;i<numLastPushed;++i) {
+ const uint64_t nwid = b.template at<uint64_t>(p); p += 8;
+ const uint64_t ts = b.template at<uint64_t>(p); p += 8;
+ np->_lastPushedComs.set(nwid,ts);
+ }
+ }
+
private:
void _sortPaths(const uint64_t now);
RemotePath *_getBestPath(const uint64_t now);