sharpsnmplib
sharpsnmplib copied to clipboard
GetResponseAsync -> SocketException -> AddressFamilyNotSupported
I found bug what hapening when i invoke many GetBulk requests with one socket. The bug is played only for large (more than 20) number of requests After several successful queries, an SocketException occurs with the AddressFamilyNotSupported.
OS: Win7 64 Framework versrion: 4.5.2 Lib versrion: 10.0.1
Minimal code for reproduce
private async void button3_Click(object sender, EventArgs e)
{
Task.Run(() => {
Test();
});
}
private async void Test()
{
IPEndPoint endPoint = new IPEndPoint(new IPAddress(new byte[] { 192, 168, 0, 1}), 161);
OctetString community = new OctetString("public");
using (var soc = endPoint.GetSocket()) {
IList<Variable> varsCache = new List<Variable>(10);
string colOid = "some.column.oid.of.big.table";
ObjectIdentifier lastOid = new ObjectIdentifier(colOid);
while (true) {
varsCache.Clear();
varsCache.Add(new Variable(lastOid));
try {
var message = new GetBulkRequestMessage(0, VersionCode.V2, community, 0, 20, varsCache);
var response = await message.GetResponseAsync(endPoint, soc);
var vars = response.Variables();
foreach (Variable var in vars) {
lastOid = var.Id;
}
if (!lastOid.ToString().StartsWith(colOid)) {
break;
}
}
catch (SocketException exception) {
if (exception.SocketErrorCode == SocketError.AddressFamilyNotSupported) {
throw new Exception("oh");
}
throw;
}
}
return;
}
}
PS: I found very similar problem https://stackoverflow.com/questions/42579158/uwp-sendtoasync-from-socket-results-in-addressfamilynotsupported
I write quick fix based on SnmpMessageExtension.GetResponseAsync that not using pool for SocketAsyncEventArgs and test my code. And the problem is eliminated.
Fix code(not sure that is correct, only for demo):
public static async Task<ISnmpMessage> GetResponseAsyncFix(ISnmpMessage request, IPEndPoint receiver, Socket udpSocket)
{
var bytes = request.ToBytes();
var bufSize = udpSocket.ReceiveBufferSize = Messenger.MaxMessageSize;
var registry = new UserRegistry();
var info = new SocketAsyncEventArgs();
info.RemoteEndPoint = receiver;
info.SetBuffer(bytes, 0, bytes.Length);
using (var awaitable1 = new SocketAwaitable(info)) {
await udpSocket.SendToAsync(awaitable1);
}
int count;
var reply = new byte[bufSize];
var args = new SocketAsyncEventArgs();
EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
try {
args.RemoteEndPoint = remote;
args.SetBuffer(reply, 0, bufSize);
using (var awaitable = new SocketAwaitable(args)) {
count = await udpSocket.ReceiveAsync(awaitable);
}
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.TimedOut) {
throw new System.TimeoutException("timeout");
}
throw;
}
var response = MessageFactory.ParseMessages(reply, 0, count, registry)[0];
var responseCode = response.TypeCode();
if (responseCode == SnmpType.ResponsePdu || responseCode == SnmpType.ReportPdu) {
var requestId = request.MessageId();
var responseId = response.MessageId();
return response;
}
throw new Exception("operation");
}
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
This is an old issue, but I believe I'm encountering the same situation.
I have a NET5 server doing mass SNMP operations. About 1000 requests to different hosts every 10 minutes. I recently switched from SnmpSharpNet to SharpSnmp in order to take advantage of async operations. Between the two versions, this was the only change and I began getting constant errors on my production server.
Unfortunately, I trap all "SocketException" and rethrow a Timeout in my code without logging, so I can't be sure of the real exception type. One thing for sure, is that after 2 days and half, repetitively I start receiving lot of SocketException, and not only on the tasks using this lib, but every socket based tasks (other tcp/udp communications).
I did a quick look at the source, and if I understand correctly, for every operations you call receiver.GetSocket()
which create a new Socket class for every call, then use it here, but never dispose or close it? Could this be simply due to a missing Dispose()?
Should have been fixed by #136 since release 12.0.0.