title: Undefined reference to 'DTLS_client_method'
body: <p>I'm currently trying to implement DTLS on android in order to encrypt UDP datagrams.
  For this, I built the openssl-android project <a href="https://github.com/guardianproject/openssl-android" rel="nofollow">available here</a>, from this I got two shared libraries libssl.so and libcrypto.so which I renamed libsslx.so and libcryptox.so to avoid confusion with the included library in the android system. </p>
  
  <p>Then I put these files (and so for the openssl header folder) into my android project under the jni folder with the following structure:</p>
  
  <pre><code>jni-&gt;|-&gt;includes---&gt;openssl---&gt;header files
       |
       |-&gt;precompiled-|-&gt;libcryptox.so
       |              |
       |              |-&gt;libsslx.so
       |
       |-&gt;Android.mk
       |
       |-&gt;security.cpp
  </code></pre>
  
  <p>Content of the Android.mk file:</p>
  
  <pre><code>LOCAL_PATH := $(call my-dir)
  
  include $(CLEAR_VARS)
  
  LOCAL_MODULE := sslx
  LOCAL_SRC_FILES := precompiled/libsslx.so
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/includes
  include $(PREBUILT_SHARED_LIBRARY)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE := cryptox
  LOCAL_SRC_FILES := precompiled/libcryptox.so
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/includes
  include $(PREBUILT_SHARED_LIBRARY)
  
  include $(CLEAR_VARS)
  
  LOCAL_MODULE    := security
  LOCAL_SRC_FILES := security.cpp
  LOCAL_SHARED_LIBRARIES := sslx cryptox
  
  include $(BUILD_SHARED_LIBRARY)
  </code></pre>
  
  <p>Content of the security.cpp file</p>
  
  
  
  <pre><code>1 #include &lt;jni.h&gt;
  2 #include &lt;string.h&gt;
  3 #include &lt;sys/types.h&gt;
  4 #include &lt;sys/socket.h&gt;
  5 #include &lt;netinet/in.h&gt;
  6 #include &lt;arpa/inet.h&gt;
  
  7 extern "C" {
  
  8  #include "openssl/bio.h"
  9  #include "openssl/ssl.h"
  10 #include "openssl/err.h"
  
  11 struct sockaddr_in dst;
  
  12 static int const SOCKET_ERROR = 1000;
  13 static int const SOCKET_CREATED = 1100;
  14 static int const BIO_ERROR = 1200;
  15 static int const BIO_CREATED = 1300;
  16 static int const CTX_ERROR = 1400;
  17 static int const CTX_CREATED = 1500;
  18 static int const SSL_ERROR = 1600;
  19 static int const SSL_CREATED = 1700;
  
  20 void Java_ch_gt_gcservjni_TestOpenSSLJni_initOpenSSL(JNIEnv *pEnv, jobject jObj){
  21      SSL_load_error_strings();
  22      ERR_load_BIO_strings();
  23          OpenSSL_add_all_algorithms();
  24 }
  
  25 jlong Java_ch_gt_gcservjni_TestOpenSSLJni_startConnection(JNIEnv *pEnv, jobject jObj, jstring jAddress, jint jPort){
  
  26    char *address;
  
  27      jclass clazz = pEnv-&gt;GetObjectClass(jObj);
  28      jmethodID mid = pEnv-&gt;GetMethodID(clazz, "printMessage", "(I)V");
  29      if(mid == 0) return -1;
  
  30      address = 0;
  31      if (jAddress) {
  32          address = (char *)pEnv-&gt;GetStringUTFChars( jAddress, 0);
  33          if (!jAddress) return 0;
  34      }
  
      //Socket creation/////////////////////////////////////////////////////////////////////////////
  35      int sock = 0;
  36      int port = (int)jPort;
  
  37      struct sockaddr_in addr;
  38      addr.sin_addr.s_addr = htonl(INADDR_ANY);
  39      addr.sin_port = htons(port);
  
  40      sock = socket(PF_INET, SOCK_DGRAM, 0);
  41      if(sock &lt; 0){
  42          pEnv-&gt;CallVoidMethod(jObj, mid, SOCKET_ERROR);
  43      }else{
  44          pEnv-&gt;CallVoidMethod(jObj, mid, SOCKET_CREATED);
  45      }
  
      ///////////////////////////////////////////////////////////////////////////////////////////////
  
      //Basic IO functionalities initialisation//////////////////////////////////////////////////////
  46      BIO* cnx = BIO_new_dgram(sock, BIO_NOCLOSE);
  47      if(cnx == NULL){
  48          pEnv-&gt;CallVoidMethod(jObj, mid, BIO_ERROR);
  49      }else{
  50          pEnv-&gt;CallVoidMethod(jObj, mid, BIO_CREATED);
  51      }
      ///////////////////////////////////////////////////////////////////////////////////////////////
  
  52      struct sockaddr_in dst;
  53      struct sockaddr* d = (struct sockaddr*)&amp;dst;
  
  54      dst.sin_family = AF_INET;
  55      dst.sin_port = htons(port);
  56      dst.sin_addr.s_addr = inet_addr(address);
  
      //Set the BIO connection
  57      int err = BIO_dgram_set_peer(cnx, d);
  
      //Initialisalisation of the Context///////////////////////////////////////////////////////////
  58      SSL_CTX *ctx = SSL_CTX_new(DTLSv1_client_method());
  59      if(ctx == NULL){
  60          pEnv-&gt;CallVoidMethod(jObj, mid, CTX_ERROR);
  61      }
  62      else{
  63          pEnv-&gt;CallVoidMethod(jObj, mid, CTX_CREATED);
  64      }
  
  65      SSL_CTX_set_read_ahead(ctx, 1);
  66      SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM:aNull");
  
  67      SSL *ssl = SSL_new(ctx);
  68      if(ssl == NULL){
  69          pEnv-&gt;CallVoidMethod(jObj, mid, SSL_ERROR);
  70      }
  71      else{
  72          pEnv-&gt;CallVoidMethod(jObj, mid, SSL_CREATED);
  73      }
  
  74      SSL_set_bio(ssl, cnx, cnx);
  75      SSL_set_connect_state(ssl);
  76      return 0;
  77   }
  
  78 }
  </code></pre>
  
  <p>And here's the problem, when I build this code, all the functions are OK except the most important one which is the DTLSv1_client_method() when I initialize the context object at the line 58.</p>
  
  <p>The generated error is this one:</p>
  
  <pre><code>/Applications/eclipse_bundle_mac/android-ndk-r8d/toolchains/arm-linux-androideabi-      4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/security/security.o: in function Java_ch_gt_gcservjni_TestOpenSSLJni_startConnection:jni/security.cpp:107: error: undefined reference to 'DTLSv1_client_method'
  </code></pre>
  
  <p>So it seems that the function is not referenced in my builded library, I checked my header files, the DTLS functions are there, I checked at the android-config.mk file of the openssl-android project to see if the functions were not excluded from the buid result and I tried to see the content of the .so files without success, btw I'm working on Mac OS X.</p>
  
  <p>Has anyone got experience about DTLS on android? I'll appreciate some help for this problem.</p>
  
  <p>EDIT: I managed to get the content of my .so files with the arm-linux-androideabi-objdump tool and no trace of any DTLS function. It maybe comes from the openssl build process I did, but it's strange because DTLS wasn't discarded in android-config.mk. </p>