A Confused Programmer's Blog

This blog is dedicated to C# and Java programming that I happen to do for living – with accent on curious cases and with sincere intent to make the world of coding a slightly better place as a result

Preventing TCP packets from growing in size

Recently I was setting up environment with WAN emulation on ESX VMs. The basic setup contained Windows XP/7 VM connected to Windows server VM with WAN emulator in the middle (Ubuntu VM). Traffic sent from XP machine utilized the bandwidth set by the WAN emulator; however, traffic sent from Windows 7/2008 was really struggling to rise above 15KB/sec.

After looking at sniffer’s traces I discovered that while XP client was continuously sending packets of 1514 bytes length:

VMs with more advanced OS were trying to optimize performance by increasing packet size:

The larger packets were dropped (never arrived to the destination), sender waited 300ms for timeout and started again with smaller packets until deciding again to go up with sizes (as the trace above shows) and repeating the vicious cycle. After some research I discovered that the feature responsible for this optimization is “Large Send Upload” option that is supported by more advanced NICs, which explains why XP VMs didn’t try this optimization. Here’s how we can disable it:

There’s also a programmatic solution to disable this feature on-the-fly. It goes something like this:

public static bool DisableLargeUploadOffload()
{
 RegistryKey networkAdapters = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\CLASS\{4D36E972-E325-11CE-BFC1-08002BE10318}");
 const string largeUploadOffloadKey = "*LsoV1IPv4";
 bool hasUpdatedAnything = false;
 foreach (var adapterNum in networkAdapters.GetSubKeyNames())
 {
  if (!adapterNum.StartsWith("0")) continue;
  RegistryKey concreteAdapter = networkAdapters.OpenSubKey(adapterNum, true);
  if (concreteAdapter == null) continue;
  if (concreteAdapter.GetValueNames().Contains(largeUploadOffloadKey))
  {
   Console.WriteLine("Disabling large upload TCP offload for {0}", concreteAdapter);
   concreteAdapter.SetValue(largeUploadOffloadKey, "0");
   hasUpdatedAnything = true;
  }
 }
 return hasUpdatedAnything;
}

After the registry is updated, it is necessary to restart network adapters – either by simply rebooting the VMs or by using WMI (check out Win32_NetworkAdapter table’s Enable() and Disable() methods).

One Response so far.

  1. Hey! Just to let you know that my last name is also Dvorkin ( and I’m also a programmer too :P), and I found out about you when I had the brilliant idea of purchasing this domain! You are a faster thinker than me 🙂

    Cheers

Subscribe to email feed

  • RSS
  • Delicious
  • Digg
  • Facebook
  • Twitter
  • Linkedin
  • Youtube

REST Assured and une

If you stumbled onto this article, it is safe to ...

Getting rid of Error

Since I upgraded my Windows 8 to Windows 10, I ...

Bypassing EULA step

We are working on automated testing of virtual appliance. This appliance ...

How I got rid of "Ac

OVF is a VMware virtual appliance format which allows you ...

My use-case of Perfo

In my blog I am set on a mission to ...

Twitter updates

RSS not configured