OK, for anyone finding this in the future, you need to create your certificates and sign them appropriately.
Here are the commands for linux:
//Generate a private key
openssl genrsa -des3 -out server.key 1024
//Generate Certificate signing request
openssl req -new -key server.key -out server.csr
//Sign certificate with private key
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
//Remove password requirement (needed for example)
cp server.key server.key.secure
openssl rsa -in server.key.secure -out server.key
//Generate dhparam file
openssl dhparam -out dh512.pem 512
Once you've done that, you need to change the filenames in server.cpp and client.cpp.
server.cpp
context_.use_certificate_chain_file("server.crt");
context_.use_private_key_file("server.key", boost::asio::ssl::context::pem);
context_.use_tmp_dh_file("dh512.pem");
client.cpp
ctx.load_verify_file("server.crt");
Then it should all work!
The compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits.
Your criticism is entirely justified.
I discuss this problem in detail here:
Closing over the loop variable considered harmful
Is there something you can do with foreach loops this way that you couldn't if they were compiled with an inner-scoped variable? or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then?
The latter. The C# 1.0 specification actually did not say whether the loop variable was inside or outside the loop body, as it made no observable difference. When closure semantics were introduced in C# 2.0, the choice was made to put the loop variable outside the loop, consistent with the "for" loop.
I think it is fair to say that all regret that decision. This is one of the worst "gotchas" in C#, and we are going to take the breaking change to fix it. In C# 5 the foreach loop variable will be logically inside the body of the loop, and therefore closures will get a fresh copy every time.
The for
loop will not be changed, and the change will not be "back ported" to previous versions of C#. You should therefore continue to be careful when using this idiom.
Best Answer
This is done in order to make sure that
connection
object outlives the asynchronous operation: as long as the lambda is alive (i.e. the async. operation is in progress), theconnection
instance is alive as well.