harald
KDE
Posted by harald
 in KDE
 on Saturday, November 29, 2008 @ 19:07

For some reason, I like using bleeding edge mail clients. The frequent crashes keep me productive (no “new mail arrived” popups to interrupt my work) as well as my co-workers (no mail with more than 20 words from me).

With the latest improvements, KMail became an even better mail client. Digging through company mail became almost pleasant. Time to fiddle around with it:

KMail using WebKit on OS X

This screen shot shows KMail on Mac OS X, using WebKit instead of KHTML to render the mails. Why, do you ask? Heat up a flame war? No, just to give a choice. I prefer KHTML on Linux, but WebKit on OS X, since it’s significantly easier to build due to fewer dependencies (I have neither fink nor mac ports installed, so every external lib is a bit of a hassle).

So here I go again, the patch is ugly enough to ensure instability. Time to go back to work.

Disclaimer: Don’t apply the patch, really, don’t, unless you are a developer who dislikes mail. It doesn’t block external images yet, so regardless of your KMail settings, you’ll inform every spammer on opening a spam mail. That is, if you’re able to open a mail at all, of course.

tbastian
Graphics View
Graphics Items
Kinetic
Multimedia
Posted by tbastian
 in Graphics View, Graphics Items, Kinetic, Multimedia
 on Friday, November 28, 2008 @ 11:20

When I started working on our multimedia framework (aka Phonon) our goal was pretty simple and clear : we needed sound and video support in Qt. We had 3 systems to support and thus 3 completely different underlying API to implement our backends. It was tough and we worked hard on it. But then we got some cool demos and we saw that basic multimedia integration in a cross-platform way is actually possible. We struggled a lot but we got there. The mediaplayer demo is a nice little app that’s fully cross-platform and easy to understand.

Having a look at the bigger picture we realized that another great feature of Qt 4.4 is the ability to get widgets on the canvas (aka QGraphicsView). All our features need to work correctly together. That’s the basic principle of a framework. Displaying video is usually hardware-accelerated and all multimedia API/system use their own way to the graphics card. That means no composition with other widgets, no ability to paint over it and of course no perspective transformation.
My first thought at the time was that we would never be able to achieve the goal of full integration of our own features (ie. having videos on the canvas) and that felt bad.

We still tried and our target was Qt4.5. The biggest challenge was to write our own video renderer. Until Qt 4.4 we always used the native video renderers (you know, the ones without composition at all and no transform).
The 1st thing you have to do is manage the rendering of video frames and use the Qt paint engine. This way you get all the power of Qt.
So after a few weeks of development, tweaking and bug fixing I had something working.

So TADA! (If you were at dev days you’ve already seen that)

Now you can simply do something like that with your VideoWidget:
QGraphicsScene scene;
QGraphicsView view(&scene);
scene.addWidget(videoWidget);

I’m a bit lazy so I didn’t put the code that creates the Phonon objects. You can find out in the documentation and examples how to do that.
And now you can apply transformations to your video. Add things on top with alpha-blending… Possibilities unilimited.
And now you’re probably thinking that there’s a catch… and you’re right. If you look at your CPU usage it will be high. Because now everything is done in software including resizing/transforming/compositing/drawing. So we optimized, rewrote some components provided by the system (”OMG, how can the colorspace-conversion in MS DirectShow be so slow?!”).

Still, there is a way of greatly improve performance. Simply add that line to your code:

view.setViewport(new QGLWidget);

This magical line enables OpenGL through the whole canvas including your video. So scaling/transformation/composition is done by your graphics card. Plus on Windows I also use fragment shader to do the conversion from YUV to RGB (colorspace conversion) on the GPU of your graphics.

To make it even clearer I just made up an additional demo. I simply took the “embedded dialogs” demo from the graphicsview guys and slightly changed it. You can run this videowall demo. You have to pass at least one parameter which is either a video file or a directory (that contains video files) path.
So for example you do: videowall c:\videos
An additional parameter is the dimension of the wall. By default it is 1, meaning 1 video. If you pass for example 3, it will build a video wall with 3×3 videos. I ran it successfully with 9 videos (3×3 wall) with WMV HD content that I got from here. If you want to watch those videos you need to make sure you have the necessary codecs (Windows has them by default).

You can get the little demo here Videowall demo

And if you run it with something like videowall c:\videos 3, you can get the following result:
the video wall example

Now that you have speed and functionality, you can do whatever you want with your videos including using the new animation API!

WidgetPimp
Qt
KDE
Posted by WidgetPimp
 in Qt, KDE
 on Thursday, November 27, 2008 @ 12:02

Ho, Ho, Ho! It’s December and the Widget Pimp is back with a gentle and subtle reminder. Did you realize that today there are only 27 shopping days left until Christmas Eve? More importantly that’s only 34 Pimping Days left until the end of Qt Software’s Pimp my Widget Contest. That’s right, you only have until December 31st to submit your entries. I ain’t giving extensions!

Now I know some of you didn’t make the “nice” part of someone’s “naughty or nice” list, but the prizes that come from winning the Pimp My Widget contest is, without overstating it, like winning ten World Cups in all sports combined! Let’s look at the prizes again:

  • A Segway i2 Personal Transporter—No better way to cruise in 2009
  • 3 Nokia N810 Tablets—Fresh from the trunk of my car
  • 100 Custom-Made, Limited-Edition Deluxe “Pimp My Widgets” T-Shirts—To keep you warm during that cold old winter

Feel free to check the website for more details and all that legal mumbo-jumbo that I can’t bother to say here.

Just remember the deadline December 31st, so get pimping!

Andreas
Qt
Posted by Andreas
 in Qt
 on Sunday, November 16, 2008 @ 15:16

Last Friday, we submitted a change into Qt 4.5 that fixes an old problem we’ve had with font and palette propagation in Qt. The patch appears in current snapshots and in the upcoming beta. Since this change affects code that’s essentially been the same since Qt 4.0, and Qt 4.5 is quite late for a change like this, I thought it would be worth writing a blog about it to draw some attention to it and gather some feedback.

The patch ensures that palette and font properties set on a widget by the user propagate all the way from the source to every single descendent widget, overriding application font and palette settings to the same font or palette property, and that all settings propagate correctly when changed. In short, if you want a specific font family for a form, and you assign a font defining only the family to that form, then this family will propagate through the entire form while keeping any existing font size settings intact, which is how it was always meant to work. It also ensures that new widgets are initialized with the right settings from their new ancestor widgets. The only thing that stops propagation is if the same property has been explicitly assigned to a child widget (or the child is a window that doesn’t enable WA_WindowPropagation). In this case, the child widget’s settings will take over and continue propagating.

The former behavior was to resolve fonts and palettes against the parent’s update mask only. Explicit settings applied by the parent’s ancestors, however, were lost when resolving against application font and palette settings. So if you set the font size of a form on Windows XP or Vista, this would not sometimes not apply to QComboBox or QTableView, but it would always apply to QPushButton and QLineEdit, because on Windows, QAbstractItemView has an application font family and size set by the system. The “sometimes” is the funny part, because if the above widgets’ immediate parent widget had font settings applied to them, then these settings would sometimes propagate. But put a widget between, and they would not (other funny behavior also applied).

Some background info might be useful. QFont and QPalette have many things in common. They represent two pilars in Qt’s style mechanism: the fonts, and the colors/gradients/pixmaps used by the style to render the appearance of its standard controls. Most widgets use both text and colors, and both the font and palette are subject to system settings (e.g., theme, locale, desktop settings for fonts and colors), style settings (most styles polish the palette somehow), and of course user settings. Each of the two has so many settings that it’s impractical to force the user to set them all. So instead, only the settings you change are applied, and the rest are derived from context sensitive defaults.

Now you don’t usually want to change the palette or font if you want your application to match the native look and feel. In some environments, however, changes can make a lot of sense. Changing the default font family or size may be important for accessibility (…OK, OK, or for fun). Changing the default window background color can give your form a special touch that separates it from the rest of your application (e.g., using a white background for configuration forms, regardless of the system theme, is quite common). However, you should be careful when making specific font or palette changes, because this may cause undesired effects when your changes are combined with system settings.

Now for the settings. Both QFont and QPalette represent lots of settings, or “roles”. They also both record which of these settings have been explicitly set, and which settings are left untouched. When Qt knows that only the QPalette::Window role of a certain widget has been set, this allows the rest of the palette to be derived from the widget’s ancestors, and from the application palette set (QApplication::palette allows the user to set default palette settings per widget class). If all you want is for your widget to use a larger font, then you should assign a QFont to that widget that only sets the point size (i.e., it leaves the family, bold and italic settings, etc, unset). This size should then automatically apply to the widget’s children without touching the other settings the children might have.


// Give w and its descendents a bold font, let all other
// font settings propagate from the defaults.
QFont f;
f.setBold(true);
w->setFont(f);

// If you want to keep existing settings that have been
// explicitly assigned to this widget, you may want to copy
// the current font out and make your modifications.
QFont f = w->font();
f.setBold(true);
w->setFont(f);

// Constructing a QFont completely from scratch is usually
// wrong.
QFont f;
f.setFamily(…);
f.setPointSize(12);
f.setBold(false);
f.set…
f.set…
w->setFont(f); // do I have to set this font on all other widgets as well?
// answer: no, if you want to change font or palette settings “globally”, start
// with QApplication::font or ::palette, and only set the entries that you’d
// like to change.

Note: QFont and QPalette both represent requests. Qt finds the effective/final font by comparing your settings against the font database to find the best match; see QFontInfo for details.

Assigning specific fonts or palettes to widgets is a privilege to the application author, and the application author’s settings should propagate. Qt’s kernel never uses direct assignment, but rather QApplication::font or ::palette, which provide “soft” default settings that the user can override. It’s unfortunately not uncommon that styles assign directly to widgets. This is unfortunate, because as soon as you assign specific font or palette settings to a widget, this stops propagation, which is often to the application author’s surprise. (For debugging purposes, you can check Qt::WA_SetPalette or Qt::WA_SetFont to see if the style is preventing your settings from propagating to a widget.) Styles are out of the application author’s control. Now if the app author wants a form and all widgets inside to use Qt::white for QPalette::Window, but the style explicitly assigns a gradient brush for that role to all QFrames, then the user’s settings are lost, which is bad (most should agree!). So why do styles do this? After all, the style can choose to render the widget just as it likes, regardless of the palette. Why should the style assign palettes to individual widgets at all? Usually, it’s to work around a specific limitation in Qt’s palette, font or style functionality, such as Qt’s lack of more context sensitivity for font or palette settings (e.g., if the QRadioButton font should be italic only if it’s an immediate child of a QGroupBox; Qt doesn’t support that out of the box. Also, widgets’ backgrounds are initialized using the widget’s background role, which is out of control for the style). The problem when doing so is that propagation stops for that role. But no finger-pointing; Qt’s own styles are guilty of this sin ;-). If your style assigns palettes to widgets (QStyle::polish(QWidget*)), you should take a second look and see if it’s really necessary. Your call :-).

Solution 1: Since the style isn’t forced to follow the palette, the alternate colors should be applied when the widget is rendered, leaving the widget font and palette intact. Theme-based styles (which require 3rd party APIs) in particular.

Solution 2: Report the limitation to us, and we might implement the missing functionality! :-)

QWidget tracks whether widgets have explicitly assigned QPalette and QFont settings through the attributes Qt::WA_SetPalette and Qt::WA_SetFont. Toggling this attribute from the outside is almost always wrong. Have you ever seen a snippet like this?


widget->setFont(font);
widget->setAttribute(Qt::WA_SetFont, false);

What does this code try to do? The WA_SetFont attribute does not affect propagation. Also, sometimes if propagation doesn’t seem to work, you see snippets like this show up:


bool Widget::event(QEvent *event)
{
switch (event-&gr;type()) {

case QEvent::FontChange:
child->setFont(font());
break;

This is also wrong; if child is a regular widget, propagation should work just fine. If it’s a window, you might want to enable Qt::WA_WindowPropagation for that child.

So now for a bottom line. I personally think Qt’s propagation mechanisms are very cool and well-designed. And I think we should continue developing them! This change takes a step into the realm of “let’s at least make sure it works consistently all over the place”. And then, we should look into how we can remove all explicit font and widget fiddling in our styles. One step at a time. :-)

ariya
WebKit
Graphics View
Graphics Dojo
Posted by ariya
 in WebKit, Graphics View, Graphics Dojo
 on Saturday, November 15, 2008 @ 01:05

Kinetic scrolling is the popular term to denote the scrolling of a long list with a bit of physics so that user feels like moving a wheel. Such a list view is then often referred as a flick list, caused the scrolling involves some sort of flicking gestures. Made popular in iPhone, flick list quickly invades other mobile platforms with touch screen because it just feels so natural and more usable than using the conventional approach of scroll bars.

How about Qt-based GUI applications? Up to now we do not offer the flickable list in any standard widgets. A practical approach would be to subclass QAbstractScrollArea and then implement your own. This does not really solve the problem if you have already tons of widgets based on, say, QListView, as you might not want to change the class structure and inheritance. Is there another solution?

Enter Flick Charm, today’s dojo example. This charm is only a proof of concept and will not have all the goodies found in iPhone (e.g. no overshoot or bouncing). However, making your list flickable is a matter of writing the code:

FlickCharm charm;
charm.activateOn(widget);

where widget is any class derived from QAbstractScrollArea and this of course includes very useful classes like QScrollArea, QAbstractItemView (and thus also QListView, QTableView, QTreeView, and friends) and even QGraphicsView. As a bonus, QWebView is also supported so your QtWebKit-based browser can be easily made flickable, too. The beauty of Flick Charm is it works on any of those widgets and that you do not even need to change your code!

For the code and the example, check out:

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/flickcharm
cd flickcharm && qmake && make && ./flickcharm

The secret of Flick Charm is the use of QObject::eventFilter to intercept the mouse events. From this, a state machine tracks the changes and apply the scrolling to the target widget. It was fairly straightforward to implement, evidenced from the class implementation that weighs around 300 lines of code only.

No kinetic scrolling demo is complete with a screencast. You can also watch it on YouTube or blip.tv.

Note: this Flick Charm automagically hides the scroll bars in the scroll area or web view. This is done because it does not make sense to have flickable list with still showing the scroll bars. If you are unhappy with this, enable the scroll bars again or just change the code.

Update: for PyQt users, check out the Python version of this charm, ported by Akos Polster.

ariya
WebKit
Graphics Dojo
Posted by ariya
 in WebKit, Graphics Dojo
 on Friday, November 14, 2008 @ 00:54

In some circumstances, for example on touch screen, a QtWebKit-based browser might not want to display the scroll bars. The reason does make sense, let the user pan around with the stylus or finger. In order to do that, scrolling the QWebView must be possible, even when the scroll bars are invisible.

The example below illustrates something a bit more than that. Not only the scroll bars are hidden, the user can actually use the mouse drag to pan around. In the touch screen devices, this translates to panning using the finger/stylus. The interesting part of the code is probably the use of JavaScript window.scrollX and window.scrollY to get the current scroll offset, and the function window.scrollTo to set the scroll offset, by using the wonderful QWebFrame::evaluateJavaScript. The rest of the panning logic is implemented by properly responding to the mouse events.

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/panwebview

Note: For Qt 4.5 we will have QWebFrame::scrollOffset and QWebFrame::setScrollOffset that can do the magic without the need to execute that piece of JavaScript code.

ariya
Graphics Dojo
Posted by ariya
 in Graphics Dojo
 on Monday, November 10, 2008 @ 21:44

Playing with the hue/saturation/value of the pixels in an image can be useful in some contexts. For example, if the image is used as an icon (e.g. in the tool bar), changing the hue during the mouse hover will give a subtle but nicevisual feedback to the user. In many desktop environments, the whole screen is grayscaled when the user is about to logout. For an application where there are pop-ups or other user-interface elements that need to get the user’s attention, the other part of the window can be dimmed or tinted
to a pale color.

One technically correct way to colorize an image is by iterating through the pixels, get the pixel color in HSV color space and changing its hue and saturation (potentially also the value) with the intended color. Since an image is often stored in RGB32 format, this involves a conversion to HSV, some H/V manipulation, and back conversion to RGB. An alternative, though less precise, is shown in this dojo example. Basically it is just a conversion of the pixel to grayscale through qGray function and then overdrawing it with a solid color rectangle with the Screen, Overlay or Multiply composition mode. The code, as well as the sample program, is:

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/imagetint

The picture shown in the program can be drawn in grayscale or tinted with whatever color you like (use the sliders to change the RGB components) and the composition mode that you like. Each composition mode gives a different result, just play with it to find something that suits your need. Of course, like the previous dojo example shows, you can replace the picture by dragging an image from your file manager or web browser and drop it in the window so that you can experiment the tinting with your own favorite photos.

ariya
Internet
Graphics Dojo
Posted by ariya
 in Internet, Graphics Dojo
 on Saturday, November 08, 2008 @ 16:37

At least once in his lifetime, every programmer must have written some sort of image viewer. Long time ago, the challenge is to understand the magical combination of those VGA registers tweaks, the machinery behind decoding different complicated image formats, and other low-level related stuff. These days, especially using modern toolkits, an image viewer is like a tutorial project which would be completed in one or two hours. Hence, let us raise the bar a bit higher: what if the view should be able to display the images not only from local disks, but from somewhere out there? Apparently, using QNetworkAccessManager, a module available since Qt 4.4, it could be more easier.

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/dragremote
cd dragremote && qmake && make && ./dragremote

After the image viewer is launched (it will show the picture of a place in Paris), now you can open your favorite web browser, go to web sites which have photo gallery (say Flickr or Picasa Web Albums), and then drag the image there and drop it in this viewer. Basically, the viewer gets the URL and uses the above mentioned network access manager to download the image, and then finally displays it.

No
Qt
Qt Script
XML
SCXML
Posted by No'am
 in Qt, Qt Script, XML, SCXML
 on Saturday, November 08, 2008 @ 04:36

Jump to the Qt-SCXML lab

Signals and slots have been, since the dawn of Qt, a great way to avoid spaghetti code. You can decouple the elements of the program, and have the inputs from one element and the outputs of another be connected externally with QObject::connect(…).

However, this is not always enough. Many times, when I write Qt applications, I find myself having to define a set of rules between one element’s signal and another element’s slot, based on state and some conditions.
I end up adding an intermediate slot, ‘if’ and ’switch’ statements, and end up with more spaghetti code. This spaghetti code can arguably be referred to as an “implicit state machine” - a set of rules based on state, that doesn’t look like a designed state machine.

Concurrency


There are two aspects to concurrency. When I cook spaghetti with meatballs, I can put the spaghetti on one burner, and the meatballs on the other burner, and they’ll cook concurrently. That’s equivalent to threading and QtConcurrent. The other aspect is managing my own concurrency. I have to react to the water boiling by adding salt and olive oil, react to the water boiling again by adding the pasta, react to the meatballs being ready by getting them off the stove, and react to the fire started in the kitchen by calling 911. In essence, I cook the spaghetti and meatballs “concurrently” even though I perform one task at a time. That aspect is equivalent to a finite state machine.

Coding spaghetti


The spaghetti header file with C++, Qt, and signals/slots:

Spaghetti h file


If I want to implement my spaghetti boiling mechanism in C++, I would need an intermediate function, something like this:

Spaghetti Function



This if statement is the essence of spaghetti code. I have to route the water-boiling signal through this intermediate function and end up with endless functions and if/switch statements just to implement these implicit state machines.I have to admit that I find myself writing such code pretty often. Debugging and scaling this code is like separating the spaghetti noodles from each other, one at a time (luckily in this example there are only two noodles.)With state machines, I don’t need this intermediate function. Instead, I implement the “raw” signals and slots, and author the rules/logic in SCXML:

Spaghetti Boiling SCXML

Note how I can connect to the same signal twice, and have it perform two completely different actions. And I can do that in a managed and readable way.

Real world examples



If you had it with spaghetti, here are some real world implementations you can do with Qt and SCXML.

Non-modal Dialogs

Modality comes from the imperative nature of languages like C++. It does not exist in nature. Imagine if your car would ask you “Are you Sure?” every time you stepped on the break pedal. When managing states correctly with a state machine, we don’t need modal dialogs. Run the blackjack example, press “Exit” and then “New Game” to see how a smoother UI can be achieved without modality.

Go Back

Many programs have a browser-like “Back” button. This is, however, not always easy to implement. The app has to maintain a stack of states and it needs to be able to restore each of these states. SCXML handles that with the “anchor” module. See the multimedia example for a use of anchors to achieve back-button functionality.

Internet Radio

An internet radio apps receives real-time events from 3 sources: user requests, network responses, and media-engine state changes. Handling the rules of execution and cleanup for such application can become quite complex, and formalizing it in a state-chart makes life a lot easier. This is true for every “reactive” system, a system that receives user and/or system events and has to react to them based on rules.

UI is not just graphics


I upload my music library to my new media-playing device. When I try to play my favorite Pink-Floyd album, I find out that all the songs are duplicated. Slightly irritated, I go to the first duplicated song and choose the “delete” function. After 2 seconds of nothing, I get a modal progress bar indicating that the song is being deleted. After about 20 seconds, I’m back at the menu and can play the song again.So, I had a terrible user experience, and it had nothing to do with flashy graphics. If the states of that applications were managed robustly, and I could continue browsing my song list as the track was being deleted from the disk, I could end up enjoying this device a lot more.

Duplication with the animation-framework states?



People might say this resembles the state XML in the animation framework. The two features do indeed handle “states” but with very different use cases in mind - the animation framework handles GUI states and animated transitions between them, while SCXML is a general purpose “powerhouse” state machine, and can be used without GUI at all. The programming examples above, for example, cannot be achieved easily with the animation states, while animation is harder to achieve with SCXML.

A Project Manager’s Dream



Sometimes projects managers (or other middle-managers) have little or no coding skills. Yet, they want to be able to control and understand the architecture of their product, without taking the coder’s word for it. SCXML provides a clear representation of flow requirements, and since it doesn’t “generate” code, the project manager can look at it and see why the application behaves the way it does, and even make minor changes without the fear of “breaking something”.
More info on the SCXML lab page.
Bon Appetit!

Thiago Macieira
Uncategorized
Posted by Thiago Macieira
 in Uncategorized
 on Friday, November 07, 2008 @ 15:44

No, I’m not talking about the economy. That would be past anyways… And would be completely off-topic for a technology blog.

What I’m talking about a crash of the way Internet works. Several years ago, it was predicted that, unless we moved on by 2009 or 2010, we’d face serious problems. And, like many predictions, it may or may not come true. But this blog is about a symptom of this larger problem: IPv4 is running out. Quoting from Wikipedia:

David Conrad, the general manager of IANA acknowledges, “I suspect we are actually beyond a reasonable time frame where there won’t be some disruption. Now it’s more a question of how much.”

Background

I’ve been passionate about IPv6 for several years now. In fact, that’s what brought me to KDE in the first place in 2000, which indirectly contributed for my being here where I am now, in Qt Software. I added IPv6 support to KDE as my first contribution, thus making Konqueror one of the first browsers that were IPv6-capable. For several years, I was able to see the dancing turtle at the KAME webpage. It only stopped when I moved to Europe in 2006 and had to use one of those router boxes in my ADSL lines. Since then, I haven’t had the opportunity to use IPv6 anymore.

And that’s the truth for most people and companies. That means there’s a proliferation of intranets using addresses reserved by RFC 1918 — the famous 10.x.y.z, 192.168.x.y, etc. A couple of years ago, you’d still find companies that used public IP addresses on their workstations. Today, those are rare exceptions.

We’re seeing problems with that setup now. Almost every router box you can get puts you on 192.168.0.x or 10.0.0.x. And since corporate networks use the same reserved addresses in their own networks, many people are unable to use VPN solutions because they lose access to their own local network.

Case study

Trolltech used to be a small company. In the past, the workstations in the Trolltech office in Oslo were given their own public IPs, but were firewalled against intrusions from the outside. As the company grew, we exhausted our address pool and then decided to move to private addresses, leaving the public ones for servers.

A simple setup was devised: the 10.1.0.0/16 network was assigned to the Brisbane office, 10.3.0.0/16 was assigned to Oslo, 10.4.0.0/16 was assigned to the Berlin office, 10.5.0.0/16 was assigned to Munich, and 10.6.0.0/16 was assigned to the U.S. office (then in Palo Alto). The network administrators at Trolltech probably had the good foresight of not using 10.0.* because that would clash with routers.

Now, you can expect many medium-sized companies to have similar setups, right? How about large companies? In those, however, the situation is very different. Instead of assigning large blocks per location, smaller blocks are allocated per network, just like on the Internet. That’s because the range of IPs and blocks are limited. So you can expect a 50,000- or 100,000-employee company to use a much complex scheme.

The problem

And then Nokia acquired Trolltech.

Obviously the Trolltech IP allocation was too liberal for the Nokia network. It wasn’t enough to plug cables in our routers and set-up the VPN links to an entry point to the larger Nokia intranet: we couldn’t continue using the same IPs! Every single workstation and device that was/is plugged to the network needs to change addresses: not just our workstations, but also the printers, our embedded devices, our testfarm of exotic Unix flavours and jurassic Windows versions, etc.

In order to support a progressive migration, our network administrators set up NAT in the Nokia-Trolltech router devices. That is, every machine in the Trolltech network got an IP address in a temporary network in the Nokia intranet, so that the services can be routed. Then, once the machine/service is migrated, it gets its permanent IP. That means each machine has 3 different IP addresses reserved for it and, along with it, 3 different hostnames.

For example, my machine was called “lothlorien.troll.no” (IP address 10.3.5.19). To access it from the Nokia network, one could use “lothlorien.nokia.troll.no” (10.215.5.19). Now that I’m connected to the new intranet, it’s known as “lothlorien.europe.nokia.com” (172.24.90.18).

Compounding the problem

As if that weren’t enough trouble, there are more issues. We have several services hardcoded in our internal tools, like our internal pastebin, our task tracker database, our wikis, etc. More than that, we have unit tests for the Qt network classes, for which the test server’s hostname was hardcoded.

That means someone in the Nokia intranet cannot run the unit tests: the host will resolve to the wrong IP address.

Change the tests, you say? Well, the migration isn’t complete. In particular, the machines doing the automated tests aren’t migrated, so we can’t. Even if we did, remember that we’d have to do it again…

So the trick is to add it to /etc/hosts? That solves some of the trouble, but not all. For one thing, the Qt3Support network classes use Q3Dns, which bypasses /etc/hosts. For another, the classes doing FTP tests will not work, since FTP servers doesn’t work behind NAT. And finally, our proxy tests won’t work, since we end up telling the proxy server to connect to the wrong IP address (problem solved in Qt 4.5 by using the hostname instead).

So, in the end, those of us who are doing network development are in the situation in which we have to ignore FTP and some other errors because of this issue.

(The actual solution we’re working on is to reinstall the network test server onto a VMWare image so that we can run it from anywhere, as well as distribute it sometime in the future).

What if we had had IPv6

Well, if we had had IPv6 to begin with, none of this trouble would have happened. First of all, we’d have been using public IP addresses from day 1, even if we were firewalled. Just like the old days in the Trolltech Oslo office.

The smallest allocation that is usually given is a network with a 48-bit prefix. That’s enough for 65,536 networks of 64-bit (good for 18446744073709551616 IPs, but usually you’d split the network long before that). The 64-bit number is not chosen by accident: it allows IPv6 to operate in the so-called “stateless address autoconfiguration” mode. Each network interface has its own 64-bit unique identifier known as EUI-64, which it concatenates to the 64-bit network prefix (the 48 of your allocation, plus the 16 of the network ID), forming the 128-bit IPv6 address. To do that, all it needs is a router advertising the prefix over ICMPv6. For Linux-based routers, you can install the radvd daemon to do exactly that.

That means we wouldn’t even need DHCP. That solves yet another problem of the transition: the policy of the Nokia network administrators is not to give static IP addresses to workstations. The rationale is that, by using DHCP, they are able to reuse addresses of machines not seen in a long time, as well as to find out when a network is reaching saturation. With IPv6, there’s no such problem: there’s no DHCP server to be maintained, there’s no need to reuse the address, since the chances of exhaustion are remote. Network congestion will happen long before that. And we get to keep a static IP address, so that I can ssh into my workstation from my home via VPN.

That’s assuming that we wouldn’t need a change in the network prefixes themselves. That could happen, though, since we got a brand-new 34 Mbit/s pipe, or because Nokia wanted everyone to be inside their main corporate prefix. Well, even if there were the case, there wouldn’t have been any disruption:

  1. First, we install the new hardware (routers, level 3 switches, etc.) and the new Internet connection
  2. Once the prefix is routed properly to our network elements, the routers in our networks start advertising a new IPv6 prefix
  3. Automatically, all IPv6 nodes assign a new IP address, without losing the old one. Yes, two IP addresses on the same interface (you probably have one more anyways)
  4. Then the network administrators do a search-and-replace on the DNS zone files, changing from the old prefix to the new one
  5. The routers then stop advertising the old prefix
  6. Since there would have been no NAT in place, we’d never have had the problems I presented for our FTP and proxy tests.
  7. As a final step, after the automatically-configured IP addresses expired, the old Internet connection is disabled

As a side note, if the A6 DNS record had been put on production instead of AAAA, our administrators wouldn’t even need to do a search-and-replace in step 4: it would be a single change, in one place.

Conclusion

This was just one case study, showing how stubborness to move away from IPv4 can make our lives more difficult. The predictions I mentioned above are from several years ago. And we still have not seen the migration start. I guess it will really take hitting people where it hurts the most (their pockets) for the transition to start.

I wish circumstances were different.



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.