Git Product home page Git Product logo

Comments (8)

joseph-henry avatar joseph-henry commented on August 19, 2024

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.

bbatchelder avatar bbatchelder commented on August 19, 2024

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.

joseph-henry avatar joseph-henry commented on August 19, 2024

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.

bbatchelder avatar bbatchelder commented on August 19, 2024

I will put my solution up and link to it here so you can just grab my code and try it out.

from libzt.

bbatchelder avatar bbatchelder commented on August 19, 2024

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.

joseph-henry avatar joseph-henry commented on August 19, 2024

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.

bbatchelder avatar bbatchelder commented on August 19, 2024

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.

joseph-henry avatar joseph-henry commented on August 19, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.