diff --git a/cmd/zt_service_tests/locator.go b/cmd/zt_service_tests/locator.go index 580a9c314..a724b59a9 100644 --- a/cmd/zt_service_tests/locator.go +++ b/cmd/zt_service_tests/locator.go @@ -14,6 +14,7 @@ package main import ( + "bytes" "fmt" "zerotier/pkg/zerotier" ) @@ -47,7 +48,37 @@ func TestLocator() bool { fmt.Printf("FAILED (%s)\n",err.Error()) return false } - fmt.Printf("OK %s\n",loc.String()) + locStr := loc.String() + locBytes := loc.Bytes() + fmt.Printf("OK (%d bytes)\n",len(locBytes)) + + fmt.Printf("Testing Locator Validate()... ") + if !loc.Validate(signer) { + fmt.Printf("FAILED (should have validated)\n") + return false + } + fmt.Printf("OK\n") + + fmt.Printf("Testing Locator marshal/unmarshal... ") + loc2, err := zerotier.NewLocatorFromString(locStr) + if err != nil { + fmt.Printf("FAILED (%s)\n",err.Error()) + return false + } + if !bytes.Equal(locBytes, loc2.Bytes()) { + fmt.Printf("FAILED (not equal)\n") + return false + } + loc2, err = zerotier.NewLocatorFromBytes(locBytes) + if err != nil { + fmt.Printf("FAILED (%s)\n",err.Error()) + return false + } + if !bytes.Equal(locBytes, loc2.Bytes()) { + fmt.Printf("FAILED (not equal)\n") + return false + } + fmt.Printf("OK\n") return true } diff --git a/cmd/zt_service_tests/zt_service_tests.go b/cmd/zt_service_tests/zt_service_tests.go index 3a7bcadb1..dfe63c8a7 100644 --- a/cmd/zt_service_tests/zt_service_tests.go +++ b/cmd/zt_service_tests/zt_service_tests.go @@ -6,14 +6,18 @@ import ( "runtime/debug" ) +const numToRun = 10000 + func main() { runtime.GOMAXPROCS(1) debug.SetGCPercent(10) - if !TestCertificate() { + for k:=0;k(loc)->marshal(reinterpret_cast(buf), (int) bufSize); + return reinterpret_cast(loc)->marshal(reinterpret_cast(buf), false); } char *ZT_Locator_toString( diff --git a/core/Locator.cpp b/core/Locator.cpp index a1b32afcf..47e5aa6b6 100644 --- a/core/Locator.cpp +++ b/core/Locator.cpp @@ -117,9 +117,13 @@ int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool exclu return -1; p += l; - l = (int)e->second->data[0] + 1; - Utils::copy(data + p, e->second->data, (unsigned int)l); - p += l; + l = (int)e->second->data[0]; + if (l > 0) { + Utils::copy(data + p, e->second->data, (unsigned int)l); + p += l; + } else { + data[p++] = 0; + } } Utils::storeMachineEndian< uint16_t >(data + p, 0); // length of meta-data, currently always 0 @@ -139,7 +143,7 @@ int Locator::unmarshal(const uint8_t *data, const int len) noexcept { if (unlikely(len < 8)) return -1; - m_ts = (int64_t) Utils::loadBigEndian(data); + m_ts = (int64_t)Utils::loadBigEndian(data); int p = 8; int l = m_signer.unmarshal(data + p, len - p); @@ -161,25 +165,28 @@ int Locator::unmarshal(const uint8_t *data, const int len) noexcept return -1; p += l; - l = (int)data[p] + 1; - if (l <= 1) { + if (unlikely(p + 1) > len) + return -1; + l = (int)data[p]; + if (l <= 0) { m_endpoints[i].second = EndpointAttributes::DEFAULT; + ++p; } else { m_endpoints[i].second.set(new EndpointAttributes()); Utils::copy(const_cast< uint8_t * >(m_endpoints[i].second->data), data + p, (unsigned int)l); + p += l; } - p += l; } if (unlikely((p + 2) > len)) return -1; - p += 2 + (int) Utils::loadBigEndian(data + p); + p += 2 + (int)Utils::loadBigEndian(data + p); if (unlikely((p + 2) > len)) return -1; const unsigned int siglen = Utils::loadBigEndian(data + p); p += 2; - if (unlikely((siglen > ZT_SIGNATURE_BUFFER_SIZE) || ((p + (int) siglen) > len))) + if (unlikely((siglen > ZT_SIGNATURE_BUFFER_SIZE) || ((p + (int)siglen) > len))) return -1; m_signature.unsafeSetSize(siglen); Utils::copy(m_signature.data(), data + p, siglen); diff --git a/core/Locator.hpp b/core/Locator.hpp index 84ac3f83c..4a989d07f 100644 --- a/core/Locator.hpp +++ b/core/Locator.hpp @@ -75,7 +75,7 @@ public: /** * Raw attributes data in the form of a dictionary prefixed by its size. * - * The maximum size of attributes is 256, which is more than enough for + * The maximum size of attributes is 255, which is more than enough for * tiny things like bandwidth and priority. */ uint8_t data[ZT_LOCATOR_MAX_ENDPOINT_ATTRIBUTES_SIZE]; diff --git a/pkg/zerotier/locator.go b/pkg/zerotier/locator.go index e851656bd..5b4ee2ede 100644 --- a/pkg/zerotier/locator.go +++ b/pkg/zerotier/locator.go @@ -98,8 +98,8 @@ func (loc *Locator) Bytes() []byte { if loc.cl == nil { return nil } - var buf [4096]byte - bl := C.ZT_Locator_marshal(loc.cl, unsafe.Pointer(&buf[0]), 4096) + var buf [16384]byte // larger than ZT_LOCATOR_MARSHAL_SIZE_MAX + bl := C.ZT_Locator_marshal(loc.cl, unsafe.Pointer(&buf[0]), 16384) if bl <= 0 { return nil } @@ -133,7 +133,7 @@ func (loc *Locator) UnmarshalJSON(j []byte) error { func locatorFinalizer(obj interface{}) { if obj != nil { - cl := obj.(Locator).cl + cl := obj.(*Locator).cl if cl != nil { C.ZT_Locator_delete(cl) }