Skip to content

Commit

Permalink
2.4.3: Prevent HTTP sockets from using IPv6
Browse files Browse the repository at this point in the history
  • Loading branch information
azuisleet committed Jun 10, 2021
1 parent 06d25ef commit bdc6ebf
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 deletions.
2 changes: 1 addition & 1 deletion DepotDownloader/ContentDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ private static async Task DownloadWebFile( uint appId, string fileName, string u
Directory.CreateDirectory( Path.GetDirectoryName( fileStagingPath ) );

using ( var file = File.OpenWrite( fileStagingPath ) )
using ( var client = new HttpClient() )
using ( var client = HttpClientFactory.CreateHttpClient() )
{
Console.WriteLine( "Downloading {0}", fileName );
var responseStream = await client.GetStreamAsync( url );
Expand Down
51 changes: 51 additions & 0 deletions DepotDownloader/HttpClientFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DepotDownloader
{
// This is based on the dotnet issue #44686 and its workaround at https://github.com/dotnet/runtime/issues/44686#issuecomment-733797994
// We don't know if the IPv6 stack is functional.
class HttpClientFactory
{
public static HttpClient CreateHttpClient()
{
var client = new HttpClient(new SocketsHttpHandler
{
ConnectCallback = IPv4ConnectAsync
});

var assemblyVersion = typeof(HttpClientFactory).Assembly.GetName().Version.ToString(fieldCount: 3);
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("DepotDownloader", assemblyVersion));

return client;
}

static async ValueTask<Stream> IPv4ConnectAsync(SocketsHttpConnectionContext context, CancellationToken cancellationToken)
{
// By default, we create dual-mode sockets:
// Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.NoDelay = true;

try
{
await socket.ConnectAsync(context.DnsEndPoint, cancellationToken).ConfigureAwait(false);
return new NetworkStream(socket, ownsSocket: true);
}
catch
{
socket.Dispose();
throw;
}
}
}
}
2 changes: 1 addition & 1 deletion DepotDownloader/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.4.2.0")]
[assembly: AssemblyVersion("2.4.3.0")]
10 changes: 9 additions & 1 deletion DepotDownloader/Steam3Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,12 @@ public Steam3Session( SteamUser.LogOnDetails details )
this.PackageInfo = new Dictionary<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo>();
this.AppBetaPasswords = new Dictionary<string, byte[]>();

this.steamClient = new SteamClient();
var clientConfiguration = SteamConfiguration.Create(config =>
config
.WithHttpClientFactory(HttpClientFactory.CreateHttpClient)
);

this.steamClient = new SteamClient(clientConfiguration);

this.steamUser = this.steamClient.GetHandler<SteamUser>();
this.steamApps = this.steamClient.GetHandler<SteamApps>();
Expand Down Expand Up @@ -531,6 +536,9 @@ private void DisconnectedCallback( SteamClient.DisconnectedCallback disconnected
if ( disconnected.UserInitiated || bExpectingDisconnectRemote )
{
Console.WriteLine( "Disconnected from Steam" );

// Any operations outstanding need to be aborted
bAborted = true;
}
else if ( connectionBackoff >= 10 )
{
Expand Down

0 comments on commit bdc6ebf

Please sign in to comment.