lontivero/Open.NAT

Unhandled Object DisposedException (NetworkStream) on ARM

timothyparez opened this issue · 4 comments

On an x86/x64 machine with .NET or Mono the following code works:

var discoverer = new NatDiscoverer();

var device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, 
                     new System.Threading.CancellationTokenSource());
var ip = await device.GetExternalIPAsync();

Console.WriteLine($"The external IP Address is: {ip}");

However, the same code on ARM with .Mono (tested 4.3 and 4.6) will output an error on:

var device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, new System.Threading.CancellationTokenSource());

Got a bad hardware address length for an AF_PACKET 16 8

And throw an exception on:

var ip = await device.GetExternalIPAsync();

Unhandled Exception:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.WebConnectionStream.EndWrite

This occurs on the RaspberryPI as well as other ARM devices such as the NanoPI.
Not sure whether the issue is caused by Open.NAT or Mono on ARM.

This was using the latest published NuGet package, I'll try to compile from source instead.

With the latest source from the master branch it runs on ARM.
It outputs the message:

Got a bad hardware address length for an AF_PACKET 16 8

Five times when calling DiscoverDevicesAsync,
after that the call to GetExternalIPAsync actually returns the proper address.

@timothyparez thanks for reporting this issue, i didn't have the time to review it on time. Currently I've found the time to fix defects and would like to know if you have more info about this problem.

There's not much info beyond this.
I just tried again with the latest commit from this repo and Mono 4.6.2
(stable 4.6.2.7/08fd525 Thu Dec 15 17:03:19 UTC 2016)

Sometimes the output is similar to:

Got a bad hardware address length for an AF_PACKET 16 8
Got a bad hardware address length for an AF_PACKET 16 8
Got a bad hardware address length for an AF_PACKET 16 8
Got a bad hardware address length for an AF_PACKET 16 8
Got a bad hardware address length for an AF_PACKET 16 8
The external IP Address is: xxx.xxx.xx.xx //(obfuscated for this post)

Other times it will actually throw the exception

Got a bad hardware address length for an AF_PACKET 16 8
Got a bad hardware address length for an AF_PACKET 16 8
Got a bad hardware address length for an AF_PACKET 16 8
Got a bad hardware address length for an AF_PACKET 16 8


Unhandled Exception:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
  at System.Net.WebConnectionStream.EndWrite (System.IAsyncResult r) [0x000af] in <bd46d4d4f7964dfa9beea098499ab597>:0
  at System.IO.Stream.<BeginEndWriteAsync>m__8 (System.IO.Stream stream, System.IAsyncResult asyncResult) [0x00000] in <fa1045786e7f4bb5bb0034ca8fb78913>:0
  at (wrapper delegate-invoke) System.Func`3[System.IO.Stream,System.IAsyncResult,System.Threading.Tasks.VoidTaskResult]:invoke_TResult_T1_T2 (System.IO.Stream,System.IAsyncResult)
  at System.Threading.Tasks.TaskFactory`1+FromAsyncTrimPromise`1[TResult,TInstance].Complete (TInstance thisRef, System.Func`3[T1,T2,TResult] endMethod, System.IAsyncResult asyncResult, System.Boolean requiresSynchronization) [0x00002] in <fa1045786e7f4bb5bb0034ca8fb78913>:0
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <fa1045786e7f4bb5bb0034ca8fb78913>:0
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0004e] in <fa1045786e7f4bb5bb0034ca8fb78913>:0
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in <fa1045786e7f4bb5bb0034ca8fb78913>:0

And this only happens on ARM and tested on 2 different networks with different routers.
Let me know what I can do to help.

If you need help setting a RaspberryPi or other ARM device for this, let me know.
If you have a RaspberryPI but don't have time to compile everything (takes quite long),
I could push a docker image to docker hub, you'd have to use HypriotOS then though.

(I have an image up on docker hub right now (here) but it still uses mono 4.2.3.4
and that one had a load of other issues with this library)