So, Microsoft rolls out a critical patch to fix a vulnerability in SChannel that could allow remote code execution. That patch also includes four new cipher suites (GCM) for TLS v1.2.
Three days later, the KB article is updated stating that some problems may exist on scenarios where TLS v1.2 is used. What?! Also, some other issues are being reported. The patch could just fix the vulnerability; instead it includes some new stuff that apparently is causing problems and the fix is disabling that new stuff. Way to go!
Edit 1: Disabling the new cipher suites does solve the TLS v1.2 problem for now…
Edit 2: Meanwhile, Microsoft rolled out a secondary package that removes the troublesome cipher suites and can be installed along with the previous update.
A quick comparison of different data-access times on a distributed system:
- L1 cache reference – 0.5 ns
- Branch mispredict – 5 ns
- L2 cache reference – 7 ns
- Mutex lock/unlock – 100 ns
- Main memory reference – 100 ns
- Compress 1K bytes with Zippy – 10,000 ns
- Send 2K bytes over 1 Gbps network – 20,000 ns
- Read 1 MB sequentially from memory – 250,000 ns
- Round trip within same datacenter – 500,000 ns
- Disk seek – 10,000,000 ns
- Read 1 MB sequentially from network – 10,000,000 ns
- Read 1 MB sequentially from disk – 30,000,000 ns
- Send packet CA->Netherlands->CA – 150,000,000 ns
Seen on this talk from Jeff Dean (Google).
Task.Run method was introduced in .NET 4.5 (back in 2012 I think) to simplify the cases where one needs to offload some work to the thread pool. Previously we used
TaskFactory.StartNew method which has much more flexibility – and the inherent complexity. If not used correctly, the different parameter combinations could allow strange/bogus behaviors, such as accidentally starting a task on the UI thread.
Task.Run simplifies the general case, from time to time I find myself wondering which is happening under the hood. Using some decompiler we can what
Task.Run(Action action) is doing:
public static Task Run(Action action)
StackCrawlMark stackCrawlMark = StackCrawlMark.LookForMyCaller;
return Task.InternalStartNew(null, action, null,
InternalTaskOptions.None, ref stackCrawlMark);
So, it’s using:
TaskScheduler.Default– This ensures we’re offloading to the thread pool. One of the problems of not specifying the scheduler when using
Task.Factory.StartNewis that it uses
TaskScheduler.Current, which might be other than the default. In .NET 4.5 there’s also the
TaskCreationOptions.HideSchedulerflag, which results in
TaskScheduler.Defaultwithin the created task, even if it runs on a different scheduler
TaskCreationOptions.DenyChildAttach– This ensures that tasks created within the current task that specify
TaskCreationOptions.AttachToParentwon’t actually attach to anything because they won’t “see” the current task.
It’s worth pointing that the
Task.Run call above is equivalent to:
Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
Both these arguments make sense as defaults and they are specially important when invoking external code. .NET folks actually admit they would make it the default if they could redo .NET 4.
You can find this and other useful information on the pfxteam blog; I really recommend reading it!