Not All Rotates Are Made Equal

If you are dealing with enctyption algorithms at all, you will notice bitwise rotate operation is used with regularity. While most processors have it available, not all languages do. For example, C# will force you to use shifting and or alternative, something like this:

(value >> count) | (value << (64 - count))

What might come as a surprise is that this incurs no performance penalty as compared to the native rotate operation. How come?

Well, a couple of years ago issue 4519 dealt with this exact problem. While it was deemed to disruptive to introduce rotate operation to the whole .NET system, it was possible to make JIT smarter. Whenever JIT notices operation pattern above, it will call upon native rotate operation, thus drastically improving performance.

However, since we’re talking about pattern recognition, you need to be careful how you write it. While we can write rotate operation in multitude of ways, not all of them will result in performance improvement. If you want rotate, better stick with the “official” pattern.

Avalonia ShowDialog and a Minimize Button

If you use ShowDialog in Avalonia, you will notice that under KDE/Wayland, window will retain minimize button. Even worse, minimize will hide the window, leaving its owner visible but not clickable. Slightly annoying and user might not even understand immediatelly why clicks on the main window are not working until they restore minimized dialog.

And, try as I might, I found no way to remove minimize box without removing the whole title. Since I was not in the mood to handle titleless windows, the next best thing was to close dialog window on minimize. Of course, detecting when window gets minimized is not really straightforward.

In the end, this is the code I ended up using:

PropertyChanged += (sender, e) => {
  if (e.Property == Window.WindowStateProperty && WindowState == WindowState.Minimized) {
    Dispatcher.UIThread.InvokeAsync(() => {
      WindowState = WindowState.Normal;
      Close();
    });
  }
};

We inject our check into the general PropertyChanged event handling. However, we cannot directly close window here as it will not revert focus to the owner. What we need is to ask dispatcher to invoke our code once UI thread has a spare moment. Then we restore the freshly minimized window, followed by close.

Not great, but not terrible either.

Synchronous Wait for Avalonia Dialog

Ideally, showing Avalonia dialog would be called from async method:

var frm = new Window(owner);
await frm.ShowDialog(this);

And 90% of time you’re good with that.

However, what if we don’t have async method handy? What if we really need to ShowDialog from non-async code?

Well, a bit more convoluted code can be used.

using var source = new CancellationTokenSource();
window.ShowDialog(owner).ContinueWith(t => source.Cancel(),
                                      TaskScheduler.FromCurrentSynchronizationContext());
Dispatcher.UIThread.MainLoop(source.Token);

A bit of handful and not really portable, but it does the job.

3GPP-Session-Stop-Indicator

Illustration

Fair amount of my time is spent in 3GPP specification world. Quite often I do that to figure out some minor details of random AVP I am analyzing. And no, I won’t probably go to the specification directly if search can work as well. So, imagine my surprise when I found 3GPP-Session-Stop-Indicator is specified incorrectly wherever I looked for it.

Want examples? Check it here, or here, or even here. Every time you see it specified, you will find the same data type: UTF8String. Which sounds plausible until you see it in the real world diameter snoop. There you’ll find its content is always 0xFF. So, what’s wrong with that?

If you read through RFC 6733, you will see that UTF8String data type is defined to use UTF-8. Guess what bytes sequence can NEVER appear in UTF-8? Darn 0xFF. As per RFC 3629, the highest byte value actually defined would be 0xF3. If you know anything about Diameter, the only sane answer is that this AVP is supposed to be of OctetString data type. So, where is this confusion coming?

I would place blame on ETSI TS 129.061 aka 3GPP 29.061. Incidentally, you won’t find 3GPP-Session-Stop-Indicator text anywhere in the specification. But you will find 3GPP-Session Stop Indicator defined with the following text:

3GPP Type: 11
Length: 3
Value is set to all 1.
3GPP-Session Stop Indicator value: Bit String type

Both 3GPP-Session Stop Indicator and 3GPP-Session-Stop-Indicator share code 11 with vendor 10415 (yes, we’ll ignore 3GPP calling it a “type” instead of “code”). They are the same AVP. Interestingly, length is specified as 3 which makes no sense as far as diameter goes. This is because this wasn’t originally specified for Diameter but for RADIUS. And, in RADIUS, length is indeed 3 bytes (or octets if you want to be fancy) once we add header to the single data byte. When Diameter came, 3GPP just promoted it into the new world without bothering to redefine it in any follow-up specification.

Now that we know we’re looking at the correct AVP, despite slight differences in name and length, what is the definition? It is defined as a bit string with all bits set to 1. Not UTF-8. Bit string. Which, in Diameter world, would mean its type is OctetString. And something that’s a single byte with all ones set is also known as 0xFF.

My guess is that someone originally misinterpreted “bit string” for “string” and thus it got written as UTF8String in the dictionary. Since 0xFF is just a single byte, nobody actually bothered to set it as string but they assign direct value when it comes from the sender. On consumer side, why would you even read this AVP when its value is always the same - there is no other value that 0xFF defined in any of 3FPP specifications as far as I can see. Thus, received only checks if AVP is present. Maybe some also check content but don’t bother converting to UTF-8 for a single byte. And that’s it - mystery solved - this was an OctetString all along.

Am I the first person to find this issue? I doubt it - anybody converting this to UTF-8 would see the issue. It is clearly visible in the darn Wireshark as text converts to “�” which is what UTF-8 decoder would return when it CANNOT convert. But I guess that most people looking at this were smart enough to just let it go. :)

Larger Live File System on Fedora 44

Illustration

While I am spending most of my time on Ubuntu these days, I do like to see what Fedora is up to. So, with Fedora 44 out, I started medling with installing some extra ZFS packages on top of it. However, I was soon hit with “Npt enough space” message. Fedora’s in-memory root pertition was a bit too small. But there’s a way around it.

During boot just select the main boot option and press e key. This will lead you into text editor and there just add

rd.live.overlay.size=10G

to the “linux” line.

This will make in-memory store larger (albeit you won’t see it be 10G in size). With this, I was finally able to fit ZFS on it.