Cross Qt Development!

It’s been ten months since Qt 5 has been released. The first official version was a disastrous one! 5.0.1 was a little bit better, 5.1.0 was good enough, and now we have 5.1.1 that is a great one.  As a Qt developer it’s not so hard to get used to the new version. There is a comprehensive guide here  to help developers to port their codebase from 4th to 5th Qt.

The same thing is now happening to me now. Sooner or later, I will have to port my applications to Qt5. So what’s I’m waiting for? Oh no… Backward Compatibility of The Source in Code! This makes things a little bit hard for me. Because I make and deploy my applications on Windows using latest version of Qt, but same products rely on operating system version of the Qt libraries in Linux machines. Most distributions still keep Qt4 in their repositories as main version of Qt. Obviously because of huge list of stuff that depend on 4th Qt.

So it looks best solution for me is porting the code base into a median state that the code can be compiled with both Qt 4 and 5 libraries. That sounds pretty boring. Actually it is.

I will use same approach with my previous post (Cross Platform Development). So the first rule is:

I. If there exists a way(W) to do task (T) that is compatible with both 4th and 5th Qt, use it, unless it’s  more complicated than collective complexity of Qt4-specific code (W4) and  Qt5-specific code (W5). Mathematically speaking,

if( W < W4+ W5) {
     T.do(W);
} 
else if (W > W4 + W5) {
     if(Qt5)
         T.do(W5);
     else
         T.do(W4);
}

Rule number two is obvious result of rule number one.

If there is no common code between Qt4 and 5, write both codes and choose which one to compile at compile time.

Let me show an example from Qtz project. In project files I have to take care of changes in module system. Fortunately there exist qmake macros that detect Qt version. More than this, there exist conditional directives that can be used for detecting Qt version.

QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 4): CONFIG   += C++11
lessThan(QT_MAJOR_VERSION, 5): QMAKE_CXXFLAGS += -std=c++0x

Same rule applies in source code:

CandleGraphicsItem::CandleGraphicsItem(const Candle& candle, QGraphicsItem *parent) :
    QGraphicsItem(parent), candle_(candle)
{
#if QT_VERSION >= 0x050000
    setAcceptHoverEvents(true);
#else
    setAcceptsHoverEvents(true);
#endif
    this->setY(-(candle.low_+candle.high_)/2.0);
}

Using QT_VERSION macro from <QtGlobal> header, you can detect which Qt version is used to compile your code. That’s cool🙂 Now I can compile same code with every version of Qt since 4.6 to 5.1.1.

For a detailed description on Qt4 and Qt5 read this article by KDAB guys. They have also developed an automated script to convert codes from 4th to 5th Qt.

Darchin’s Adventure

Disclaimer: Following content contains a non-technical short story about my cats.

Meet Darchin and Khepel, two lazy boys, young members of our family

Darchin (right) and Khepel (left)

Darchin is younger and more energized. He’s a hyperactive cat. You can never see him doing nothing. Khepel is more experienced. He’s a so sedate and dignified.

Today Darchin went to the roofs and he couldn’t come down. That’s a classic cat adventure. He was frightened. He was screaming and asking for someone’s help.  I tried to get it but can’t[1]. After two long hours of fear and stress, he finally came down with help of Khepel. He soothed him and showed him how to do those catish staff.

Today Darchin learned how to climb high buildings and come down safely. I’m proud of my sons🙂

Cross-platform Developmen

I would like my programs and libraries to work on different platforms, as much as possible. Primary target is always Linux and Unix-like systems of course, though I would like to provide same functionality on Windows and maybe Android and iOS. The platform, should not be a restriction for using softwares. This lead to the idea of Cross-Platform Development. Unfortunately it’s not easy. There is no accepted standardization of operation system APIs or common operations between operating systems. Developers should write code with cross-platform requirements in mind.  I’m going to describe my own experience with cross-platform development in the Artificial Intelligence Toolkit project. I encountered lots of problems and resolved some of them. This article provides a simple check-list to help developers avoid most frequent issues of cross-platform development in C/C++. Let’s go ahead🙂

The Language

I. So shalt not code in a platform-specific language.

Just don’ do that. Don’t code in C#, C++ CLI or other Microsoft tools.

C++ is cross-platform enough

C++ is cross-platform enough cause it has a compiler on every platform (at least major ones)

The Code

II. So shalt not write platform-dependent code. Even in cost of adding more dependencies.

Rule number one says that your code should not rely on platform-specific staff. That’s not using Berkeley socket API in Linux or its Windows compeer, Winsock for example. Rather than using such APIs, add a third party dependency. For above example, using ASIO to do networking may be a cross-platform solution. ASIO itself is cross-platform so your code will run on both Windows and Linux.

In the case that you are developing an operating system level API, then you have to write code for each platform and specify which code to compile using compile-time conditional directives.

void delay(int ms)
{
#ifdefined(OS_WIN32)
              Sleep(ms);
#elifdefined(OS_LINUX)
             usleep(ms*1000);
#endif
}

In the presence of standard mechanism for any task, developer should consider about using standard way rather than invoking operating system functions. Above code can be replaced with this one:

void delay(int ms)
{
    // Guaranteed to run properly on every platform if it compiles!
    std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

Second delay need C++11 support. After 2014 guys at Microsoft may decide their compiler suite not to be an outdated one and may support C++11 completely.

The Build System

III. So shalt not use a platform-specific build system. Even in cost of providing more than one build system for different platforms.

Different platforms use different build systems. Most common build systems are GNU make and Microsoft’s NMake. There are plenty of nice build script generation tools like GNU autohell, CMake, Qt’s qmake and Microsoft Visual Studo! Yes that’s true🙂 Visual Studio is an IDE that generates makefile from solution file. So it can be considered as a build script generator.

Personally I prefer autotools for both Linux and Windows. On windows it can be used with MSYS/MinGW with no problem. After all, from compiler to build system, the GNU toolchain can not be considered as a first degree citizen in Windows. That’s why you may want to compile your code with MSVC. Fortunately build systems do not conflict with each other. Simply add a visual studio project to source sandbox at the same level with your autotools files. If you feel so scrupulous, you can jail build system files in different directories and share source code between them. Such a development ecosystem will happily continue to its life with no trouble.

Digital Security: Self-protection

Sometimes I got a bothering paranoia  about my privacy. Recently I deleted my Google account because of an MITM attack. It seems that only affected users was my hometown friends. That’s why I’m gonna describe how to check validity of SSL certificates in this post. Let’s say you want to check validity of your SSL certificate of Google Plus service. The root certificate authority of *.google.com domains is Equifax. Google has announced that they’re planing to change their encryption system to use 2048-bit keys.

Protecting the security and privacy of our users is one of our most important tasks at Google, which is why we utilize encryption on almost all connections made to Google.

This encryption needs to be updated at times to make it even stronger, so this year our SSL services will undergo a series of certificate upgrades—specifically, all of our SSL certificates will be upgraded to 2048-bit keys by the end of 2013. We will begin switching to the new 2048-bit certificates on August 1st, to ensure adequate time for a careful rollout before the end of the year. We’re also going to change the root certificate that signs all of our SSL certificates because it has a 1024-bit key.

First make sure you have installed OpenSSL. Ubuntu users can install from repositories:

$ sudo make install openssl

Create a sandbox:

$ mkdir -p ~/.cert/plus.google.com/
$ cd ~/.cert/plus.google.com/

Then get the may-be affected certification. Make sure you have an un-trusted connection. Remember you want to check your connection. So don’t turn VPN or SSH Tunnel.

$ openssl s_client -showcerts -connect plus.google.com:443

Output should be something like:

CONNECTED(00000003)
depth=1 C = US, O = Google Inc, CN = Google Internet Authority
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority
-----BEGIN CERTIFICATE-----
MIIGKjCCBZOgAwIBAgIKZAPy8wABAACR3DANBgkqhkiG9w0BAQUFADBGMQswCQYD
VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu
dGVybmV0IEF1dGhvcml0eTAeFw0xMzA3MTIwOTAwMzBaFw0xMzEwMzEyMzU5NTla
MGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N
b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRUwEwYDVQQDFAwqLmdv
b2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANRk5KDRmXcTdorq
kBFq7Mz17PXY3L1XaypAA/gMju7TcS6cbMmOEhmIXX5Ul+GAxfLwmE2WSGe1K58m
++B4D153EKIXc+ilrDKt7K/BfcX1cH3qUhk6Zc3IO2PTPL3UYkWA6WiH1Ehuaf39
89FfB7Vk20Nv2QOvNOHW18qZWgbzAgMBAAGjggP9MIID+TAdBgNVHSUEFjAUBggr
BgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFArP+7JSI4++2qQ6xmNmryABbF8z
MB8GA1UdIwQYMBaAFL/AMOv1QxE+Z7qekfv8atrjaxIkMFsGA1UdHwRUMFIwUKBO
oEyGSmh0dHA6Ly93d3cuZ3N0YXRpYy5jb20vR29vZ2xlSW50ZXJuZXRBdXRob3Jp
dHkvR29vZ2xlSW50ZXJuZXRBdXRob3JpdHkuY3JsMGYGCCsGAQUFBwEBBFowWDBW
BggrBgEFBQcwAoZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l
dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcnQwDAYDVR0TAQH/
BAIwADCCAsMGA1UdEQSCArowggK2ggwqLmdvb2dsZS5jb22CDSouYW5kcm9pZC5j
b22CFiouYXBwZW5naW5lLmdvb2dsZS5jb22CEiouY2xvdWQuZ29vZ2xlLmNvbYIW
Ki5nb29nbGUtYW5hbHl0aWNzLmNvbYILKi5nb29nbGUuY2GCCyouZ29vZ2xlLmNs
gg4qLmdvb2dsZS5jby5pboIOKi5nb29nbGUuY28uanCCDiouZ29vZ2xlLmNvLnVr
gg8qLmdvb2dsZS5jb20uYXKCDyouZ29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29t
LmJygg8qLmdvb2dsZS5jb20uY2+CDyouZ29vZ2xlLmNvbS5teIIPKi5nb29nbGUu
Y29tLnRygg8qLmdvb2dsZS5jb20udm6CCyouZ29vZ2xlLmRlggsqLmdvb2dsZS5l
c4ILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmh1ggsqLmdvb2dsZS5pdIILKi5nb29n
bGUubmyCCyouZ29vZ2xlLnBsggsqLmdvb2dsZS5wdIIPKi5nb29nbGVhcGlzLmNu
ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYINKi5nc3RhdGljLmNvbYIMKi51cmNoaW4u
Y29tghAqLnVybC5nb29nbGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tgg0q
LnlvdXR1YmUuY29tghYqLnlvdXR1YmVlZHVjYXRpb24uY29tggsqLnl0aW1nLmNv
bYILYW5kcm9pZC5jb22CBGcuY2+CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5j
b22CCmdvb2dsZS5jb22CEmdvb2dsZWNvbW1lcmNlLmNvbYIKdXJjaGluLmNvbYII
eW91dHUuYmWCC3lvdXR1YmUuY29tghR5b3V0dWJlZWR1Y2F0aW9uLmNvbTANBgkq
hkiG9w0BAQUFAAOBgQBfxSnRtvvjE4rZn/JjpRoC9HrlCXNfMtg3feveIEhGA8Cl
j5aGf2H+8RBfTYzwFmykUvlYNA47de8rHU6rAMcOR7Nq2ePB8BXpsnZ4CH0mCBNz
76V3NMkECr+o+Vn9l6sAbyjqGwA0dJ3++4SM0Hjd/6jXLXt3ICgggP4eKr09fA==
-----END CERTIFICATE-----
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIDFXfhMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTIxMjEyMTU1ODUwWhcNMTMxMjMxMTU1ODUw
WjBGMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZ
R29vZ2xlIEludGVybmV0IEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEAye23pIucV+eEPkB9hPSP0XFjU5nneXQUr0SZMyCSjXvlKAy6rWxJfoNf
NFlOCnowzdDXxFdF7dWq1nMmzq0yE7jXDx07393cCDaob1FEm8rWIFJztyaHNWrb
qeXUWaUr/GcZOfqTGBhs3t0lig4zFEfC7wFQeeT9adGnwKziV28CAwEAAaOBozCB
oDAfBgNVHSMEGDAWgBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUv8Aw
6/VDET5nup6R+/xq2uNrEiQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
BAMCAQYwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20v
Y3Jscy9zZWN1cmVjYS5jcmwwDQYJKoZIhvcNAQEFBQADgYEAvprjecFG+iJsxzEF
ZUNgujFQodUovxOWZshcnDW7fZ7mTlk3zpeVJrGPZzhaDhvuJjIfKqHweFB7gwB+
ARlIjNvrPq86fpVg0NOTawALkSqOUMl3MynBQO+spR7EHcRbADQ/JemfTEh2Ycfl
vZqhEFBfurZkX0eTANq98ZvVfpg=
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
issuer=/C=US/O=Google Inc/CN=Google Internet Authority
---
No client certificate CA names sent
---
SSL handshake has read 2790 bytes and written 347 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.1
    Cipher    : ECDHE-RSA-RC4-SHA
    Session-ID: 5E2774A7C4D1B6728979A80D52831BCA524AC57A5AB5C188A1A4CB48A0314A71
    Session-ID-ctx: 
    Master-Key: 10FACBF7E9E427981439570C200715F5755B05B7CD6380C465DF0E0DA94101B4A72D918F26B3344E632AEB62927A2605
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    TLS session ticket:
    0000 - 3a 2b 6a c3 f0 81 17 22-19 77 e9 26 48 ac f0 ec   :+j....".w.&H...
    0010 - d3 99 e9 c5 e2 47 8d 6e-7c 97 e2 f3 e3 c3 1c a7   .....G.n|.......
    0020 - 70 4c f6 04 fd 54 7a 7a-63 5d 67 47 a8 27 69 aa   pL...Tzzc]gG.'i.
    0030 - 00 2c 13 c9 7c 77 8c ac-87 c5 3d 92 b5 4b 29 10   .,..|w....=..K).
    0040 - df 83 6e 2d e2 81 d9 cb-2e 80 88 2a 31 a2 e2 35   ..n-.......*1..5
    0050 - 41 17 83 d7 a7 48 3f 7d-93 56 74 f1 c9 dc c3 89   A....H?}.Vt.....
    0060 - c5 c0 bf 7f 31 ec 9e 31-3a 7a 77 a5 37 db 67 4d   ....1..1:zw.7.gM
    0070 - b2 ac e4 06 85 ce ad dc-40 00 71 6e ed f9 4d 55   ........@.qn..MU
    0080 - 12 d8 01 f9 dc 08 b6 7e-18 94 c9 25 e9 db 5f a9   .......~...%.._.
    0090 - 2a 12 de 28                                       *..(

    Start Time: 1375440311
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---

Copy content between —–BEGIN CERTIFICATE—– and —–END CERTIFICATE—– and paste it into ./plus.google.com.pem

Now you need to get certificate of the issuer. Make sure you’re using protection. Turn on SSH Tunnel  or VPN and:

$ wget http://www.geotrust.com/resources/root_certificates/certificates/Equifax_Secure_Certificate_Authority.pem

Create symbolic links by hashes:

$ c_rehash ~/.cert/plus.google.com/

Output looks like:

Doing /home/soroush/.cert/plus.google.com/
Equifax_Secure_Certificate_Authority.pem => 578d5c04.0
Equifax_Secure_Certificate_Authority.pem => 594f1775.0
plus.google.com.pem => a18bd28a.0
plus.google.com.pem => ae1123c5.0

To confirm you have a valid certificate you need to check original certificate authority against the may-be-hijacked certificate that you can see:

$ openssl s_client -CApath ~/.cert/plus.google.com/ -connect plus.google.com:443
CONNECTED(00000003)
depth=2 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = *.google.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGKjCCBZOgAwIBAgIKZAPy8wABAACR3DANBgkqhkiG9w0BAQUFADBGMQswCQYD
VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu
dGVybmV0IEF1dGhvcml0eTAeFw0xMzA3MTIwOTAwMzBaFw0xMzEwMzEyMzU5NTla
MGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N
b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRUwEwYDVQQDFAwqLmdv
b2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANRk5KDRmXcTdorq
kBFq7Mz17PXY3L1XaypAA/gMju7TcS6cbMmOEhmIXX5Ul+GAxfLwmE2WSGe1K58m
++B4D153EKIXc+ilrDKt7K/BfcX1cH3qUhk6Zc3IO2PTPL3UYkWA6WiH1Ehuaf39
89FfB7Vk20Nv2QOvNOHW18qZWgbzAgMBAAGjggP9MIID+TAdBgNVHSUEFjAUBggr
BgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFArP+7JSI4++2qQ6xmNmryABbF8z
MB8GA1UdIwQYMBaAFL/AMOv1QxE+Z7qekfv8atrjaxIkMFsGA1UdHwRUMFIwUKBO
oEyGSmh0dHA6Ly93d3cuZ3N0YXRpYy5jb20vR29vZ2xlSW50ZXJuZXRBdXRob3Jp
dHkvR29vZ2xlSW50ZXJuZXRBdXRob3JpdHkuY3JsMGYGCCsGAQUFBwEBBFowWDBW
BggrBgEFBQcwAoZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l
dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcnQwDAYDVR0TAQH/
BAIwADCCAsMGA1UdEQSCArowggK2ggwqLmdvb2dsZS5jb22CDSouYW5kcm9pZC5j
b22CFiouYXBwZW5naW5lLmdvb2dsZS5jb22CEiouY2xvdWQuZ29vZ2xlLmNvbYIW
Ki5nb29nbGUtYW5hbHl0aWNzLmNvbYILKi5nb29nbGUuY2GCCyouZ29vZ2xlLmNs
gg4qLmdvb2dsZS5jby5pboIOKi5nb29nbGUuY28uanCCDiouZ29vZ2xlLmNvLnVr
gg8qLmdvb2dsZS5jb20uYXKCDyouZ29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29t
LmJygg8qLmdvb2dsZS5jb20uY2+CDyouZ29vZ2xlLmNvbS5teIIPKi5nb29nbGUu
Y29tLnRygg8qLmdvb2dsZS5jb20udm6CCyouZ29vZ2xlLmRlggsqLmdvb2dsZS5l
c4ILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmh1ggsqLmdvb2dsZS5pdIILKi5nb29n
bGUubmyCCyouZ29vZ2xlLnBsggsqLmdvb2dsZS5wdIIPKi5nb29nbGVhcGlzLmNu
ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYINKi5nc3RhdGljLmNvbYIMKi51cmNoaW4u
Y29tghAqLnVybC5nb29nbGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tgg0q
LnlvdXR1YmUuY29tghYqLnlvdXR1YmVlZHVjYXRpb24uY29tggsqLnl0aW1nLmNv
bYILYW5kcm9pZC5jb22CBGcuY2+CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5j
b22CCmdvb2dsZS5jb22CEmdvb2dsZWNvbW1lcmNlLmNvbYIKdXJjaGluLmNvbYII
eW91dHUuYmWCC3lvdXR1YmUuY29tghR5b3V0dWJlZWR1Y2F0aW9uLmNvbTANBgkq
hkiG9w0BAQUFAAOBgQBfxSnRtvvjE4rZn/JjpRoC9HrlCXNfMtg3feveIEhGA8Cl
j5aGf2H+8RBfTYzwFmykUvlYNA47de8rHU6rAMcOR7Nq2ePB8BXpsnZ4CH0mCBNz
76V3NMkECr+o+Vn9l6sAbyjqGwA0dJ3++4SM0Hjd/6jXLXt3ICgggP4eKr09fA==
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
issuer=/C=US/O=Google Inc/CN=Google Internet Authority
---
No client certificate CA names sent
---
SSL handshake has read 2790 bytes and written 347 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.1
    Cipher    : ECDHE-RSA-RC4-SHA
    Session-ID: 948080BCEEEC76AE136086E69F1CAAC60CA67C078528E959BAE1679B3E7AF03E
    Session-ID-ctx: 
    Master-Key: 6A4F31D9A704C8FDFFA41DC13AB5010353897EDBE8918453D5A05E6DA039A5EAB2FE357475EB0C0E86A9EBAFA8A28BBC
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    TLS session ticket:
    0000 - 3a 2b 6a c3 f0 81 17 22-19 77 e9 26 48 ac f0 ec   :+j....".w.&H...
    0010 - d6 65 91 8e 9e 18 09 d4-97 58 1f 53 0f d6 47 96   .e.......X.S..G.
    0020 - a8 a0 30 8c 4c af 8e d1-58 5b 01 74 93 21 35 f9   ..0.L...X[.t.!5.
    0030 - 34 03 6a c0 1a 99 b7 36-ea 1d f5 08 c1 d4 84 ed   4.j....6........
    0040 - 3d fe 84 39 a8 76 76 66-5a 34 68 06 55 7b 54 d3   =..9.vvfZ4h.U{T.
    0050 - 84 6b 10 2d 1d 26 91 3c-6c ae f7 2e 74 a8 dd a1   .k.-.&.<l...t...
    0060 - 05 6a 93 67 f4 f8 78 a3-27 36 f1 fa 5f 7d c7 45   .j.g..x.'6.._}.E
    0070 - 11 7c 52 9b 31 3e 28 3b-f9 d4 f0 23 7d 18 b8 cd   .|R.1>(;...#}...
    0080 - 9d 17 06 83 01 d2 5f 6f-e3 03 db cd ac 47 55 26   ......_o.....GU&
    0090 - 06 18 98 86                                       ....

    Start Time: 1375441275
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

There is a lot of information in output though only important on is the last line (marked as red).

Is it all over? Not yet. Check all certificate hierarchy of target domain. Certificates of mail.google.com and plus.google.com was NOT VALID since August 1st 2013 from my connection.

Take care.

The Legend of C++: Learn me if you can

This is my forth and last year in university studying to get bachelor’s degree in software engineering. Since the first year (2009) I’ve introduced to C++ Programming Language. Since year three (fall 2011) I was teaching C++ new students as a teacher assistant. Though sometimes I feel I’ve never learned even a bit of C++ ! I never stopped studying, coding but every day I learn a new, surprising fact about the language.

"Learn Me if You Can" Poster :D

“Learn Me if You Can” Poster😀

The last interesting feature of C++ I learned today, is called surrogate call functions. That is the simple fact:

Template arguments can be callable objects or function pointers

After a short WTF moment, I realized that the feature is extremely useful. Then I passed a little longer “Why didn’t i think of that?” moment. Finally my mind get addicted to the subject. I can’t wait to use it in my codes🙂

template<typename FT1, typename FT2>
class callable_object {
  FT1 *f1;
  FT2 *f2;

public:
  callable_object(FT1 *_f1, FT2 *_f2):f1(_f1), f2(_f2) { }
  operator FT1*() { return f1; }
  operator FT2*() { return f2; }
};

void f(const int& i){ /* do something useful */ }
void g(const double& d){ /* do something useful */ }

int main() {
  callable_object<void(const int&), void(const double&)> c(foo, bar);
  c(10);   // ==> f
  c(10.0); // ==> g
}

LibAIT: A General-purpose Artificial Intelligence Toolkit

Recently I had a course on Constraint Satisfaction Problems in my university. The subject was so interesting to me. We studied basic concepts and recent works on CSPs, and also, distributed CSPs and parallel search algorithms used to solve this kind of problems. Among these staff Asynchronous Backtracking was the most interesting to me. For my final project of CSP course, My friend and I have implemented an improvement of ABT that uses polynomial space. Better improvements exists, especially Agile-ABT which we failed to implement in-time.

A Simple Constraint Satisfaction Problem

A Simple Constraint Satisfaction Problem

During research phase I was looking around to find similar projects. Then encountered Geocode project (generic constraint development environment). Its documentation says:

gecode-logo

Gecode Logo

Gecode is a toolkit for developing constraint-based systems and applications. Gecode provides a constraint solver with state-of-the-art performance while being modular and extensible. Gecode is:
open, comprehensive, efficient, documented, free, portable, parallel and tested

Well, that is a very nice set of features. The developers of project have done a great job. They pretend that gecode is most optimized and efficient infrastructure of CSP:

Gecode offers excellent performance with respect to both runtime and memory usage. It won all gold medals in all categories at the MiniZinc Challenges from 2008 to 2012: 2012, 2011, 2010, 2009, and 2008.

Unfortunately the library has some drawbacks making it useless for simple CSP staff. Most importantly, I think gecode is hard to use. In order to solve a CSP you need to inherit from a class of library, add constraint sets by hand, in code, and compile. While it’s so flexible and fast, it’s a little bit hard to use. This gives me an idea: Implement an easy-to-use, portable and efficient library for doing CSP staff.

At first glance it looks like re-inventing the wheel. Well, it’s kind of. But not exactly! The library I’m thinking of is much more simpler. It’s supposed to be fast. Most important feature that I need to include, is support for XCSP 2.1 specification. This file structure is the standard XML-based description of constraint satisfaction problems developed by International CSP Solver Competition comitee. User should be able to implement his/her own CSP solver, on the top of infrastructure layer. Infrastructure do the boring, repeated staff. Generic CSP solver should be able to read CSPs from XCSP files or streams and then convert them into a well-defined data structures, very close to formal definition of CSP. Any other solver is supposed to inherit from GCSPS. Nothing special is here. This is just matter of OOP design. I must take care to avoid making a disaster design. You know, it’s very easy in C++ to make a mess😀

The killer feature of my (not-yet-born) library, is support for XCSP. XCSP 2.1 is very flexible. You can define constraints, relations, functions and generalized constraints in terms of XML. It supports MathML and a C-style notation with a set of functions to declare implicit constraints.

For example consider N-Queens problem. One can easily define a predicate to “implicitly” specify constraints:

<predicates nbPredicates="1">
<predicate name="P0">
  <parameters>int X0 int X1 int X2</parameters>
   <expression> 
    <functional>and(ne(X0,X1),ne(abs(sub(X0,X1)),X2))</functional>
  </expression>
</predicate>
</predicates>

And then, many constraints can refer to same predicate:

<constraints nbConstraints="66">
  <constraint name="C0" arity="2" scope="V0 V1" reference="P0">
    <parameters>V0 V1 1</parameters>
  </constraint>
  <constraint name="C1" arity="2" scope="V0 V2" reference="P0">
    <parameters>V0 V2 2</parameters>
  </constraint>
  <!-- And so on... -->
</constraints>

This makes things simpler. You don’t need to have a huge C set. I’m planning to simulate same idea in C++ code using function pointers. It’s not very easy… I will need a good XML parser and I need to implement very fast lexer/parser pair to interpret C-style notation of functional objects.

It may be fast enough to catch gecode!

Final word: I am planning to add AI-planner infrastructure (PDDL parser, etc) in far future. That’s why it’s named libAIT instead of libGCSP !

Challenge accepted🙂

C++1y Concurrent Data Structures

Parallelism!

Parallelism and Concurrency in Modern C++

I always come across this situation: I have some program, or multiple programs running concurrently, they need to share a data. The shared data needs to be protected against read/write violation.

Well, this is known as reader/writer problem: one of traditional problems used to teach concurrency concepts in operating system courses. The well-known solution is lock-do-unlock idiom. Using threading APIs (say POSIX) that they provide mutex mechanism, this can be easily implemented using a mutex per object OR a mutex per critical area. For the first scenario, I have a better solution for object-oriented programming languages that I’m gonna describe it in this post. And also I’ll provide a possible syntax for C++.

Motivation

Suppose we have a class that it’s instances are supposed to be shared between threads. Of course all operations that modify the class should not be concurrent. Well this is not true for all possible scenarios We may want to do two independent operations, say o1 and o2, concurrently if we can make sure about safety. We can have a data structure containing two independent structures, and providing independent operations, o1 and o2, each one modifying one of internal structures. Anyway.. that’s not the common case I wanna present.

The well-known solution to reader-writer problem is to lock the critical area by mutexes. This is a bad solution. Why? First it’s inelegant. Second It lacks readability: Which mutex guards which data? Third its error-prone. What happens when you forgot an unlock? Obviously deadlocks.

This is a small example of my experience with AIT library. I was implementing Asynchronous Backtracking algorithm using a multi-agent fashion. Each agent has two threads: Message reader and Algorithm workhorse. First one reads messages from a TCP socket and stores them in a queue, second reads message from that queue and erases recently read message. Here is the code:

// Algorithm workhorse
pthread_mutex_lock(&this->messageRW);   // lock the door
P_Message x = this->messageQueue.pop(); // do the job
pthread_mutex_unlock(&this->messageRW); // get out of there
// somewhere else, in another thread
while (true) {
    P_Message message;
    solver->listener->recvMessage(message);
    pthread_mutex_lock(&(solver->messageRW));   // lock the door
    solver->messageQueue.push(message);         // do the job
    pthread_mutex_unlock(&(solver->messageRW)); // get out of there
    sem_post(&solver->messageCount);
}

That’s not the end of world. Everything works fine, though consider the fact that there are some scenarios in which you need to do the first part many many many times! Yes that’s the points. You probably don’t want to wrap each modification code in the ugly lock / unlock pairs.

Better Solution

So far, we have seen how bad mutexes are🙂 Just kidding. They’re great. And I’m doing to present a mutex-based solution to remove lock / unlock pairs.

Suppose C++ has a keyword concurrent. This keywords comes before a complex type and magic begins. All non-const accessors and modifiers, in fact every single method or operator implemented in the class/structure, becomes wrapped in the lock/unlock pairs. For example, consider the std::queue class. We want to suppose that it’s safe to read head of the queue and append a new item to its tail at the same time (well I mean in two threads.) But it’s obviously not safe to append enqueue two items. In my very own solution, all I need to do is just put the keyword concurrent before declaration of std::queue.

concurrent std::queue<protocols::csp::abt::P_Message> messageQueue;

This keyword makes compiler to generate a code which in every non-const method of std::queue is wrapped in a lock / unlock pair. Consider following method which is implemented somewhere in stdlib.

std::queue::push_back(const T& item){
    // some of stdlib secret codes
}

Happens to be

std::queue::push_back(const T& item){
    // this->mutex->lock()
    // some of stdlib secret codes
    // this->mutex->unlock()
}

This way I can tell the compiler to call which function. In fact to generate the code tha calls which function. But before this, I need to tell the complier, which classes are supposed to be used concurrently. So I can use same keyword before class definition. Adding that keyword, causes compiler to generate binary code for two versions of each non-const operation:

// somewhere in stdlib accessed by #include <queue>
namespace std{
template <typename T>
concurrent class queue{
    // class definition
}

In the worst case, making a class concurrent, almost doubles size of generated binary. On the other hand there exist some design scenarios in which programmer don’t want to make a non-const operation thread-safe. One may need to have a partially concurrency-enabled class. For this two reason, it’s better to provide ability to declare concurrency status of each method separately. Again, using the same magic keyword: concurrent.

Of course there are ambiguities within this proposal. This post describes main idea. I’m gonna submit the detailed proposal to the C++ WG comitee, SG1, tomorrow.