Sunday, May 1, 2011

64 Bit NPN (no-worky)

‹prev | My Chain | next›

Last night, I was able to get ssldump to sniff SPDY packets. It was still not a full SPDY session, so tonight I hope to get a little closer.

Fortunately, Carson McDonald has done yoeman's work toward this, and presented a gist of how to get NPN working with eventmachine.

Rather than following the very detailed instructions in that gist, I wonder if it will "just work". So I copy the npn-enabled event machine script and give it a whirl:
➜  spdy git:(master) ✗ ruby ./examples/npn_spdy_server.rb
./examples/npn_spdy_server.rb:35:in `post_init': undefined method `set_negotiable_protocols' for #<SPDYHandler:0x00000000ef9fc0> (NoMethodError)
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-0.12.10/lib/em/connection.rb:45:in `block in new'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-0.12.10/lib/em/connection.rb:36:in `instance_eval'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-0.12.10/lib/em/connection.rb:36:in `new'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-0.12.10/lib/eventmachine.rb:1430:in `event_callback'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run'
from ./examples/npn_spdy_server.rb:66:in `<main>'
OK I am none too surprised at that. Maybe a newer version of eventmachine?
➜  spdy git:(master) ✗ gem uninstall eventmachine
Successfully uninstalled eventmachine-0.12.10
➜ spdy git:(master) ✗ gem install eventmachine --pre
Building native extensions. This could take a while...
Successfully installed eventmachine-1.0.0.beta.3
1 gem installed
Unfortunately, I get no joy from the most recent pre-release version of the gem:
➜  spdy git:(master) ✗ ruby ./examples/npn_spdy_server.rb
./examples/npn_spdy_server.rb:35:in `post_init': undefined method `set_negotiable_protocols' for # (NoMethodError)
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3/lib/em/connection.rb:45:in `block in new'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3/lib/em/connection.rb:36:in `instance_eval'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3/lib/em/connection.rb:36:in `new'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3/lib/eventmachine.rb:1384:in `event_callback'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3/lib/eventmachine.rb:199:in `run_machine'
from /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3/lib/eventmachine.rb:199:in `run'
from ./examples/npn_spdy_server.rb:66:in `<main>'
OK. That does not solve it. To the google machine! Er... Google is also unable to find anything about set_negotiable_protocols. So... to the githubs!

It is on github that I find the answer, none too surprisingly from Carson:https://github.com/carsonmcdonald/eventmachine/commit/ba9c3892e05fc8c50e6bed88c3a381e0a922c74d. Ah. Turns out I did need to install Carson's eventmachine fork—he added the set_negotiable_protocols method in a branch of his fork. So...
➜  repos  git clone git://github.com/carsonmcdonald/eventmachine.git
Cloning into eventmachine...
remote: Counting objects: 3792, done.
remote: Compressing objects: 100% (1263/1263), done.
remote: Total 3792 (delta 2702), reused 3339 (delta 2398)
Receiving objects: 100% (3792/3792), 794.81 KiB | 159 KiB/s, done.
Resolving deltas: 100% (2702/2702), done.
➜ repos cd eventmachine
➜ eventmachine git:(master) git checkout tls-npn
Branch tls-npn set up to track remote branch tls-npn from origin.
Switched to a new branch 'tls-npn'
➜ eventmachine git:(tls-npn) rake gem
...
That last command errors because I need rake-compiler installed:
➜  eventmachine git:(tls-npn) gem install rake-compiler
Successfully installed rake-compiler-0.7.8
1 gem installed
➜ eventmachine git:(tls-npn) rake gem
(in /home/cstrom/repos/eventmachine)
rake-compiler must be configured first to enable cross-compilation
rake-compiler must be configured first to enable cross-compilation
rake-compiler must be configured first to enable cross-compilation
rake-compiler must be configured first to enable cross-compilation
mkdir -p pkg
Successfully built RubyGem
Name: eventmachine
Version: 1.0.0.beta.3
File: eventmachine-1.0.0.beta.3.gem
mv eventmachine-1.0.0.beta.3.gem pkg/eventmachine-1.0.0.beta.3.gem
Better. And with that, I can install the version of eventmachine with set_negotiable_protocols:
➜  eventmachine git:(tls-npn) gem install pkg/eventmachine-1.0.0.beta.3.gem
Building native extensions. This could take a while...
Successfully installed eventmachine-1.0.0.beta.3
1 gem installed
Unfortunately, I still get no joy. When I attempt to access the eventmachine server, I continue to get the set_negotiable_protocols error. Sigh. So I really did need to follow along with the entire list of instructions that Carson provided.

Following along with his instructions, I first install an npn-enabled version of openssl:
➜  eventmachine git:(tls-npn) cd ..
➜ repos mkdir openssl
➜ repos cd !$
➜ repos cd openssl
➜ openssl mkdir openssl-dist
➜ openssl cvs -d anonymous@cvs.openssl.org:/openssl-cvs co openssl
zsh: correct 'cvs' to '_cvs' [nyae]? n
zsh: command not found: cvs
➜ openssl sudo apt-get install cvs
# weep uncontrollably
➜ openssl cvs -d anonymous@cvs.openssl.org:/openssl-cvs co openssl
zsh: correct 'cvs' to '_cvs' [nyae]? n
# No, sadly, I really do want cvs...
The authenticity of host 'cvs.openssl.org (194.97.152.144)' can't be established.
RSA key fingerprint is 55:c1:16:04:82:09:3a:ac:88:14:27:3f:46:7c:25:e4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'cvs.openssl.org,194.97.152.144' (RSA) to the list of known hosts.
cvs server: WARNING: Read-only repository access mode selected via `cvs -R'.
Using this option to access a repository which some users write to may
cause intermittent sandbox corruption.
cvs checkout: Updating openssl
U openssl/.cvsignore
U openssl/ACKNOWLEDGMENTS
U openssl/CHANGES
U openssl/CHANGES.SSLeay
U openssl/Configure
...
cvs checkout: Updating openssl/util/pl
U openssl/util/pl/BC-32.pl
U openssl/util/pl/Mingw32.pl
U openssl/util/pl/OS2-EMX.pl
U openssl/util/pl/VC-32.pl
U openssl/util/pl/linux.pl
U openssl/util/pl/netware.pl
U openssl/util/pl/ultrix.pl
U openssl/util/pl/unix.pl
With that, I can compile:
➜  openssl-src  ./config --prefix=$HOME/repos/openssl/openssl-dist/
Operating system: x86_64-whatever-linux2
Configuring for linux-x86_64
Configuring for linux-x86_64
no-ec-nistp224-64-gcc-128 [default] OPENSSL_NO_EC_NISTP224_64_GCC_128 (skip dir)
no-gmp [default] OPENSSL_NO_GMP (skip dir)
no-jpake [experimental] OPENSSL_NO_JPAKE (skip dir)
no-krb5 [krb5-flavor not specified] OPENSSL_NO_KRB5
no-md2 [default] OPENSSL_NO_MD2 (skip dir)
no-rc5 [default] OPENSSL_NO_RC5 (skip dir)
no-rfc3779 [default] OPENSSL_NO_RFC3779 (skip dir)
no-shared [default]
no-store [experimental] OPENSSL_NO_STORE (skip dir)
no-zlib [default]
no-zlib-dynamic [default]
...

Since you've disabled or enabled at least one algorithm, you need to do
the following before building:

make depend

Configured for linux-x86_64.
So, I make depend:
➜  openssl-src  make depend
making depend in crypto...
make[1]: Entering directory `/home/cstrom/repos/openssl/openssl-src/crypto'
making depend in crypto/objects...
...
make[1]: Nothing to be done for `depend'.
make[1]: Leaving directory `/home/cstrom/repos/openssl/openssl-src/tools'
And... make install:
➜  openssl-src  make install
...
make[2]: Leaving directory `/home/cstrom/repos/openssl/openssl-src/engines/ccgost'
make[1]: Leaving directory `/home/cstrom/repos/openssl/openssl-src/engines'
making install in apps...
make[1]: Entering directory `/home/cstrom/repos/openssl/openssl-src/apps'
installing openssl
installing CA.sh
installing CA.pl
installing tsget
make[1]: Leaving directory `/home/cstrom/repos/openssl/openssl-src/apps'
making install in test...
make[1]: Entering directory `/home/cstrom/repos/openssl/openssl-src/test'
make[1]: Nothing to be done for `install'.
make[1]: Leaving directory `/home/cstrom/repos/openssl/openssl-src/test'
making install in tools...
make[1]: Entering directory `/home/cstrom/repos/openssl/openssl-src/tools'
make[1]: Leaving directory `/home/cstrom/repos/openssl/openssl-src/tools'
installing libcrypto.a
installing libssl.a
cp libcrypto.pc /home/cstrom/repos/openssl/openssl-dist/lib/pkgconfig
chmod 644 /home/cstrom/repos/openssl/openssl-dist/lib/pkgconfig/libcrypto.pc
cp libssl.pc /home/cstrom/repos/openssl/openssl-dist/lib/pkgconfig
chmod 644 /home/cstrom/repos/openssl/openssl-dist/lib/pkgconfig/libssl.pc
cp openssl.pc /home/cstrom/repos/openssl/openssl-dist/lib/pkgconfig
chmod 644 /home/cstrom/repos/openssl/openssl-dist/lib/pkgconfig/openssl.pc
Nice. Hopefully I am getting close. I export some openssl-related environment variables:
➜  openssl-src  export PATH=$HOME/repos/openssl/openssl-dist/bin/:$PATH
➜ openssl-src export LD_LIBRARY_PATH=$HOME/repos/openssl/openssl-dist/lib
➜ openssl-src export PKG_CONFIG_PATH=$HOME/repos/openssl/openssl-dist/lib/pkgconfig
➜ openssl-src export CPATH=$HOME/repos/openssl/openssl-dist/include
And finally, I re-build the gem:
➜  eventmachine git:(tls-npn) gem install pkg/eventmachine-1.0.0.beta.3.gem
Building native extensions. This could take a while...
ERROR: Error installing pkg/eventmachine-1.0.0.beta.3.gem:
ERROR: Failed to build gem native extension.

/home/cstrom/.rvm/rubies/ruby-1.9.2-p0/bin/ruby extconf.rb
checking for rb_trap_immediate in ruby.h,rubysig.h... no
checking for rb_thread_blocking_region()... yes
checking for inotify_init() in sys/inotify.h... yes
checking for writev() in sys/uio.h... yes
checking for rb_thread_check_ints()... yes
checking for rb_time_new()... yes
checking for sys/event.h... no
checking for epoll_create() in sys/epoll.h... yes
creating Makefile

make
...
g++ -shared -o rubyeventmachine.so ssl.o ed.o cmain.o em.o rubymain.o page.o pipe.o kb.o binder.o -L. -L/home/cstrom/.rvm/rubies/ruby-1.9.2-p0/lib -Wl,-R/home/cstrom/.rvm/rubies/ruby-1.9.2-p0/lib -L. -rdynamic -Wl,-export-dynamic -L/home/cstrom/repos/openssl/openssl-dist/lib -Wl,-R -Wl,/home/cstrom/.rvm/rubies/ruby-1.9.2-p0/lib -L/home/cstrom/.rvm/rubies/ruby-1.9.2-p0/lib -lruby -lssl -lcrypto -ldl -lpthread -lrt -ldl -lcrypt -lm -lc
/usr/bin/ld: /home/cstrom/repos/openssl/openssl-dist/lib/libssl.a(s23_srvr.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/home/cstrom/repos/openssl/openssl-dist/lib/libssl.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [rubyeventmachine.so] Error 1


Gem files will remain installed in /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3 for inspection.
Results logged to /home/cstrom/.rvm/gems/ruby-1.9.2-p0@spdy/gems/eventmachine-1.0.0.beta.3/ext/gem_make.out
Ugh.

Unfortunately, I have to call it a night at this point. Initial research into that error seems to indicate that it is a 64 bit thing and that openssl and 64 bit machines are difficult, at best. I think I will give it a try in a 32 bit VM tomorrow.


Day #7

No comments:

Post a Comment