Comments (8)
Thanks for reporting this. I've taken a look and found what could be a bug. In the libzt.cs
that I presume you're using (found in examples/csharp/ExampleWindowsCSharpApp
), the prototype for zts_get_address()
does in fact have an incorrect return type. Merely changing that from void
to int
and running your code yielded a valid address.
Let me know if you can't replicate this or you run into anything else.
from libzt.
Hey, so I had already modified the signature of zts_get_address(), not only to return an int, but also so that the signature matches the header.
Here is whats in the examples/csharp/ExampleWindowsCSharp/libzt.cs file:
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void zts_get_address(ulong nwid, IntPtr addr, int addrlen);
This is what I changed it to:
[DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int zts_get_address(ulong nwid, IntPtr addr, int addressFamily);
based on what I see in libzt.h:
ZT_SOCKET_API int ZTCALL zts_get_address(
const uint64_t nwid, struct sockaddr_storage *addr, const int address_family);
This definitely seems to work better than when I was trying to pass an addrlen as the last parameter. But I am not a C/C++ developer, and honestly my pinvoke experience is also pretty limited.
But I am kinda worried that I can take the same code, run it 10 times, and 1/3 to 1/2 of the time the app randomly crashes without an exception even being raised.
from libzt.
I see. So it's still crashing at the same point you mentioned, only not as often? I'll test it a bit more.
from libzt.
I will put my solution up and link to it here so you can just grab my code and try it out.
from libzt.
Had a bit of a breakthrough...I was looking for code examples using PtrToStructure and happened across some code on stack overflow that was using GCHandles and pinning the memory.
I hate that its essentially cargo cult coding, but I decided it couldn't hurt to try, and now the app is stable with the following code for GetAddress():
static IPAddress GetAddress(ulong nwid)
{
int err = 0;
int sockAddrInSize = Marshal.SizeOf(typeof(libzt.SockAddrIn));
byte[] addressPtrBuffer = new byte[sockAddrInSize];
GCHandle addressPtrHandle = GCHandle.Alloc(addressPtrBuffer, GCHandleType.Pinned);
IntPtr addressPtr = GCHandle.ToIntPtr(addressPtrHandle);
int hasAddress = 0;
while((hasAddress = libzt.zts_has_address(nwid)) != 1)
{
Console.WriteLine("No address assigned yet...");
Thread.Sleep(500);
}
if ((err = libzt.zts_get_address(nwid, addressPtr, 2)) < 0)
{
throw new Exception("Failed to get IP address");
}
Console.WriteLine("We have an IP address...");
byte[] ipbytes = null;
try
{
Console.WriteLine("About to call PtrToStructure, we often crash here");
var address = Marshal.PtrToStructure<libzt.SockAddrIn>(addressPtr);
Console.WriteLine("PtrToStructure happened and we didn't crash");
ipbytes = BitConverter.GetBytes(address.Addr);
}
finally
{
addressPtrHandle.Free();
}
return new IPAddress(ipbytes);
}
And if you change GCHandleType from Pinned to Normal, the app will always encounter a fatal exception:
Managed Debugging Assistant FatalExecutionEngineError : The runtime has encountered a fatal error.
The address of the error was at 0x738483e0, on thread 0xc3c. The error code is 0xc0000005.
This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code.
Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
This is well beyond my experience level, but hopefully it helps you diagnose the issue...
from libzt.
Thanks for investigating. It does make sense to use a Pinned handle in this case since it will prevent the memory contents from moving beneath your feet. If this particular method is now 100% reliable I will close this ticket. If not, let me know and I can continue to look into this.
from libzt.
Yeah, I think this is reliable now. I am working on some more advanced issues like being able to use zts_select() - which I have mostly working - and zts_fcntl() - which I can't seem to get to work for the life of me. I'll open up a new issue for those and have demo code available.
I'd really like to contribute by helping flush out the .NET interop. I am also working on a project for my company that I suspect will have us purchasing an enterprise account if I can get the proof of concept working.
from libzt.
That would be great. The .NET interop is largely untested so if you get hung up on something don't hesitate to ask, chances are it's something that hasn't been implemented yet and most things should be minor tweaks at this point.
I'll await the ticket on the zts_fcntl() function.
from libzt.
Related Issues (20)
- Java process does not exit after finishing libzt work HOT 3
- Memory leak if libzt events aren't consumed by user app
- How to deal with scenarios that requires cancelling? HOT 5
- .NET binding: `Node.InitSetEventHandler` is not really optional as stated in example HOT 1
- .NET binding: Socket.Send behavior is unexpected HOT 2
- Error installing ZeroTier Nuget, visual studio 2022 .net framework project
- xcodebuild: error: Unable to read project 'zt.xcodeproj'. Reason: The project âztâ is damaged and cannot be opened due to a parse error. Examine the project file for invalid edits or unresolved source control conflicts.
- NodeService heap corruption after ZTS_EVENT_PEER_PATH_DISCOVERED HOT 6
- Required fixes to build libzt on Windows HOT 4
- cmake errors for java build HOT 1
- unable to use compiled jar HOT 6
- Java multithreaded server hangs
- java windows does not compile dll HOT 16
- Script fail in Ubuntu HOT 1
- Script fail in Windows HOT 5
- Question about android example from documentation
- iOS clang error: no such file Build/Products/Release/zt.framework/Versions/A/zt
- C# Optional Setup Doesn't Seem So Optional -> System.ExecutionEngineException HOT 1
- C# node.IdString can leave out leading zeroes
- Java Windows: Could not get IPs correctly and Could not send data via sockets. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
đ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. đđđ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google â¤ď¸ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libzt.