libgnutlsxx link problems

Boyan Kasarov bkasarov at gmail.com
Mon Oct 5 15:42:32 CEST 2009


Hello,
I am having problems linking against libgnutlsxx.

The test program I used:
( NOTE It requires the helper functions from
http://www.gnu.org/software/gnutls/manual/gnutls.html#Helper-function-for-TCP-connections wrapped in extern "C" )

#include <iostream>
#include <stdexcept>
#include <gnutls/gnutls.h>
#include <gnutls/gnutlsxx.h>
#include <cstring> /* for strlen */

/* A very basic TLS client, with SRP authentication.
 * written by Eduardo Villanueva Che, changed by Boyan Kasarov.
 */

#define MAX_BUF 1024
#define SA struct sockaddr

#define CAFILE "ca.pem"
#define USERNAME "username"
#define PASSWORD "password"
#define MSG "GET / HTTP/1.0\r\n\r\n"

extern "C"
{
    int tcp_connect(void);
    void tcp_close(int sd);
}


int main(void)
{
    int sd = -1;
    gnutls_global_init();

    try
    {
        /* Allow connections to servers that have OpenPGP keys as well.
         */
        gnutls::client_session session;

        /* X509 stuff */
        gnutls::certificate_credentials credentials;

        /* SRP stuff */
        gnutls::srp_client_credentials srp_credentials;

        /* sets the trusted cas file
         */
        credentials.set_x509_trust_file(CAFILE, GNUTLS_X509_FMT_PEM);

        /* enter username and passowrd
         */
        srp_credentials.set_credentials(USERNAME, PASSWORD);

        /* put the x509 credentials to the current session
         */
        session.set_credentials(credentials);

        /* put the srp credentials to the current session
         */
        session.set_credentials(srp_credentials);

        /* Use default priorities */
        session.set_priority ("NORMAL:+SRP:+SRP-RSA:+SRP-DSS:-DHE-RSA",
NULL);

        /* connect to the peer
         */
        sd = tcp_connect();
        session.set_transport_ptr((gnutls_transport_ptr_t) sd);

        /* Perform the TLS handshake
         */
        int ret = session.handshake();
        if (ret < 0)
        {
//             gnutls_perror(ret);
            throw std::runtime_error("Handshake failed");
        }
        else
        {
            std::cout << "- Handshake was completed" << std::endl;
        }

        session.send(MSG, strlen(MSG));
        char buffer[MAX_BUF + 1];
        ret = session.recv(buffer, MAX_BUF);
        if (ret == 0)
        {
            throw std::runtime_error("Peer has closed the TLS
connection");
        }
        else if (ret < 0)
        {
            throw std::runtime_error(gnutls_strerror(ret));
        }

        std::cout << "- Received " << ret << " bytes:" << std::endl;
        std::cout.write(buffer, ret);
        std::cout << std::endl;

        session.bye(GNUTLS_SHUT_RDWR);
    }
    catch (gnutls::exception &ex)
    {
        std::cerr << "Exception caught: " << ex.what() << std::endl;
    }

    if (sd != -1)
        tcp_close(sd);

    gnutls_global_deinit();

    return 0;
}

The problem I have is this:

derex at laptop ~/workspace/gnutls-test $ g++ ./test.cpp -lgnutlsxx
/tmp/cccjLXmv.o: In function `main':
test.cpp:(.text+0x15f): undefined reference to
`gnutls::srp_client_credentials::srp_client_credentials()'
test.cpp:(.text+0x188): undefined reference to
`gnutls::srp_client_credentials::set_credentials(char const*, char
const*)'
test.cpp:(.text+0x721): undefined reference to
`gnutls::srp_client_credentials::~srp_client_credentials()'
test.cpp:(.text+0x74b): undefined reference to
`gnutls::srp_client_credentials::~srp_client_credentials()'
/tmp/cccjLXmv.o:(.gcc_except_table+0xac): undefined reference to
`typeinfo for gnutls::exception'
collect2: ld returned 1 exit status

This errors appears if I use versions from 2.8.3 upto 2.9.4 (snapshot
20091004 from http://daily.josefsson.org/gnutls/ ) , I couldn't find
where gnutls source is , I didn't test versions before 2.8.3

The way I see it the link problem consists of 2 problems:

**** SRP related classes don't get build because of missing ENABLE_SRP
preprocessor flag ( even if srp is enabled from configure ). It can be
fixed by including config.h in lib/gnutlsxx.cpp, here is patch :

diff --git a/lib/gnutlsxx.cpp b/lib/gnutlsxx.cpp
index 83453f0..cdca728 100644
--- a/lib/gnutlsxx.cpp
+++ b/lib/gnutlsxx.cpp
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include <gnutls/gnutlsxx.h>

 namespace gnutls


**** The second problem is missing typeinfo for some classes, including
gnutls::exception in the example. I used this hack to fix it:

diff --git a/lib/libgnutlsxx.map b/lib/libgnutlsxx.map
index f049df4..62f6c12 100644
--- a/lib/libgnutlsxx.map
+++ b/lib/libgnutlsxx.map
@@ -24,7 +24,11 @@ GNUTLS_1_6
 {
   global:
     extern "C++" {
-      gnutls*;
+      gnutls::*;
   };
+
+  # export typeinfo names and structures
+  _ZTI*;
+
   local: *;
 };

However I think some solution like explained at this url - 
http://gcc.gnu.org/wiki/Visibility could be implemented for the C++
bindings.

Boyan Kasarov







More information about the Gnutls-devel mailing list