1

I'm encountering a situation on production that is difficult to debug.
Sometimes the connection to an external service can't be established with the following error:

System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 93.39.196.220:443
   at System.Net.Sockets.Socket.InternalEndConnect(IAsyncResult asyncResult)
   at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
   at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

Sometimes it works without any problem. This is what I've tried:

  • Replacing the way I perform the connection (from Restsharp to HttpClient)
    • HttpClient is long lived as suggested by this post
  • Adjusting the timeout
  • Using async and sync code
  • Analyzing SNAT Port exhaustion
    SNAT Connections

SNAT Failures

More info:

  • The IPs of my server are authorized by the external service (and if they weren't I would be receiving a different error)
  • While on production I'm having the problem I'm able to connect to the service from development or staging (so it shouldn't be a problem with the external service)
  • While I'm having trouble contacting this service I don't have trouble contacting a different (but similar) service
  • I'm on a Web App Service on Azure. I'm using the .NET framework 4.7.2
  • The same code sometimes works and sometimes it doesn't

This is (more or less) the current iteration

private async Task<ResultSet> SendRequestAsync(HttpClient client, RateRequestBody document){
    ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
    var response = await client.PostAsXmlAsync(baseUrl + "/XMLServices", document);
    if (response.IsSuccessStatusCode){
      ...
    }else{
      ...
    }
}

Any ideas on what I might have missed? Thanks

Maurizio Pozzobon
  • 2,924
  • 7
  • 33
  • 44

2 Answers2

0

As per this Microsoft doc: "HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors."

There could be a number of reasons depending on the service you are connecting to. What would be helpful to know is :

  1. please check what type of service is the web app connecting to? Is there a client side timeout (the web app is the client)?
  2. Also can you verify if the server receives the requests from the web app?

For more info you can refer this link.

  • I'm already using HttpClient as a static variable instantiated once. The web app is the client and nothing I do to the timeout changes anything. I've checked but the server doesn't get my requests – Maurizio Pozzobon Oct 15 '21 at 09:11
0

The answer may lay here: Default SecurityProtocol in .NET 4.5

Assuming both servers are operating correctly, one works fine with your client code and the other gives you problems based on your 'More Info' section: "While I'm having trouble contacting this service I don't have trouble contacting a different (but similar) service"

I recommend removing or commenting out the following line and giving it a try:

//ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

...or replace it with:

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
Rick Miller
  • 21
  • 1
  • 3
  • Thanks, I'll give it a try but I have my doubts, as I said the problem is intermittent, so I doubt that the service changes protocol at random intervals, and while it is "down" from production I can still call it (with the same code) from a different environment – Maurizio Pozzobon Nov 03 '21 at 08:16