c - OpenSSL and Network namespace - Closed -


i developing application using openssl library. new openssl library. application working correctly until tested within network namespace. application hangs @ ssl_connect. using sockets in blocking mode. read somewhere should use non-blocking mode instead solve issue. switched blocking sockets non-blocking sockets code still gets stuck @ ssl_connect method in client.

i have simple client-server program nothing fancy stuff. have added ssl methods inside them make them secure. works when run them inside terminal when switch network namespace , run inside virtual network, client code hangs @ ssl_connect. not able understand may causing problem. appreciated!

here code server.c file:

#include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #include <errno.h> #include <sys/select.h>  #include <sys/types.h> #include <unistd.h> #include <string.h>  #include <openssl/ssl.h> #include <openssl/err.h>  #define server_port  12345  #define true             1 #define false            0  main (int argc, char *argv[]) {    int    i, len, rc, on = 1;    int    listen_sd, max_sd, new_sd;    int    desc_ready, end_server = false;    int    close_conn;    char   buffer[80];    struct sockaddr_in   addr;    struct timeval       timeout;    fd_set        master_set, working_set;    char ch='a';      //ssl initiation     ssl_load_error_strings();     err_load_bio_strings();     err_load_ssl_strings();     ssl_library_init();     openssl_add_all_algorithms();     ssl_method *meth = sslv3_server_method();     ssl_ctx *ctx = ssl_ctx_new(meth);     ssl_ctx_use_certificate_file(ctx, "truststore.pem", ssl_filetype_pem);     ssl_ctx_use_privatekey_file(ctx, "privatekey.key", ssl_filetype_pem);     /*************************************************************/    /* create af_inet stream socket receive incoming       */    /* connections on                                            */    /*************************************************************/    listen_sd = socket(af_inet, sock_stream, 0);    if (listen_sd < 0)    {       perror("socket() failed");       exit(-1);    }     /*************************************************************/    /* allow socket descriptor reuseable                   */    /*************************************************************/    rc = setsockopt(listen_sd, sol_socket,  so_reuseaddr,                    (char *)&on, sizeof(on));    if (rc < 0)    {       perror("setsockopt() failed");       close(listen_sd);       exit(-1);    }     /*************************************************************/    /* set socket non-blocking.  of sockets    */    /* incoming connections non-blocking since  */    /* inherit state listening socket.   */    /*************************************************************/    rc = ioctl(listen_sd, fionbio, (char *)&on);    if (rc < 0)    {       perror("ioctl() failed");       close(listen_sd);       exit(-1);    }     /*************************************************************/    /* bind socket                                           */    /*************************************************************/    memset(&addr, 0, sizeof(addr));    addr.sin_family      = af_inet;    addr.sin_addr.s_addr = htonl(inaddr_any);    addr.sin_port        = htons(server_port);    rc = bind(listen_sd,              (struct sockaddr *)&addr, sizeof(addr));    if (rc < 0)    {       perror("bind() failed");       close(listen_sd);       exit(-1);    }     /*************************************************************/    /* set listen log                                   */    /*************************************************************/    rc = listen(listen_sd, 32);    if (rc < 0)    {       perror("listen() failed");       close(listen_sd);       exit(-1);    }     /*************************************************************/    /* initialize master fd_set                              */    /*************************************************************/    fd_zero(&master_set);    max_sd = listen_sd;    fd_set(listen_sd, &master_set);     /*************************************************************/    /* initialize timeval struct 3 minutes.  if no        */    /* activity after 3 minutes program end.           */    /*************************************************************/    timeout.tv_sec  = 3 * 60;    timeout.tv_usec = 0;     /*************************************************************/    /* loop waiting incoming connects or incoming data   */    /* on of connected sockets.                          */    /*************************************************************/       {       /**********************************************************/       /* copy master fd_set on working fd_set.     */       /**********************************************************/       memcpy(&working_set, &master_set, sizeof(master_set));        /**********************************************************/       /* call select() , wait 5 minutes complete.   */       /**********************************************************/       printf("waiting on select()...\n");       rc = select(max_sd + 1, &working_set, null, null, &timeout);        /**********************************************************/       /* check see if select call failed.                */       /**********************************************************/       if (rc < 0)       {          perror("  select() failed");          break;       }        /**********************************************************/       /* check see if 5 minute time out expired.         */       /**********************************************************/       if (rc == 0)       {          printf("  select() timed out.  end program.\n");          break;       }        /**********************************************************/       /* 1 or more descriptors readable.  need         */       /* determine ones are.                         */       /**********************************************************/       desc_ready = rc;       (i=0; <= max_sd  &&  desc_ready > 0; ++i)       {          /*******************************************************/          /* check see if descriptor ready            */          /*******************************************************/          if (fd_isset(i, &working_set))          {             /****************************************************/             /* descriptor found readable - 1   */             /* less has looked for.  being done   */             /* can stop looking @ working set   */             /* once have found of descriptors   */             /* ready.                                      */             /****************************************************/             desc_ready -= 1;              /****************************************************/             /* check see if listening socket     */             /****************************************************/             if (i == listen_sd)             {                printf("  listening socket readable\n");                /*************************************************/                /* accept incoming connections      */                /* queued on listening socket before   */                /* loop , call select again.              */                /*************************************************/                               {                   /**********************************************/                   /* accept each incoming connection.  if       */                   /* accept fails ewouldblock,     */                   /* have accepted of them.  other      */                   /* failure on accept cause end */                   /* server.                                    */                   /**********************************************/                   new_sd = accept(listen_sd, null, null);                   if (new_sd < 0)                   {                      if (errno != ewouldblock)                      {                         perror("  accept() failed");                         end_server = true;                      }                      break;                   }                    /**********************************************/                   /* add new incoming connection     */                   /* master read set                            */                   /**********************************************/                   printf("  new incoming connection - %d\n", new_sd);                   fd_set(new_sd, &master_set);                   if (new_sd > max_sd)                      max_sd = new_sd;                    /**********************************************/                   /* loop , accept incoming   */                   /* connection                                 */                   /**********************************************/                } while (new_sd != -1);             }              /****************************************************/             /* not listening socket, therefore   */             /* existing connection must readable             */             /****************************************************/             else             {                printf("  descriptor %d readable\n", i);                close_conn = false;  ssl* ssl; ssl = ssl_new(ctx); ssl_set_fd(ssl, i);  //handshake  ssl_accept(ssl); printf("\nhandshake done\n");  int result = ssl_read(ssl, &ch, sizeof(ch));  if(result<0) {     printf("\nreading error"); } ++ch; result = ssl_write(ssl, &ch, sizeof(ch));   if(result<0) {     printf("\nwriting error"); }                /*************************************************/                /* if close_conn flag turned on, need */                /* clean active connection.      */                /* clean process includes removing        */                /* descriptor master set ,            */                /* determining new maximum descriptor value  */                /* based on bits still turned on in */                /* master set.                               */                /*************************************************/                if (close_conn)                {                   close(i);                   fd_clr(i, &master_set);                   if (i == max_sd)                   {                      while (fd_isset(max_sd, &master_set) == false)                         max_sd -= 1;                   }                }             } /* end of existing connection readable */          } /* end of if (fd_isset(i, &working_set)) */       } /* end of loop through selectable descriptors */     } while (end_server == false);     /*************************************************************/    /* cleanup of sockets open                  */    /*************************************************************/    (i=0; <= max_sd; ++i)    {       if (fd_isset(i, &master_set))          close(i);    } } 

here code client.c file:

/**************************************************************************/ /* generic client example used connection-oriented server designs */ /**************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <openssl/ssl.h> #include <openssl/err.h>   #define server_port  12345  main (int argc, char *argv[]) {    int    len, rc;    int    sockfd;    char   send_buf[80];    char   recv_buf[80];    struct sockaddr_in   addr;    char ch = 'a';    int result;       //ssl initiation     ssl_load_error_strings();     err_load_bio_strings();     err_load_ssl_strings();     ssl_library_init();     openssl_add_all_algorithms();     ssl_method *meth;     meth = sslv3_client_method();     ssl_ctx *ctx;     ssl* ssl;     ctx = ssl_ctx_new(meth);         result = ssl_ctx_load_verify_locations(ctx, "truststore1.pem", 0);     printf("\nca load result = %d\n", result);     printf("\nssl initialized");     /*************************************************/    /* create af_inet stream socket               */    /*************************************************/    sockfd = socket(af_inet, sock_stream, 0);    if (sockfd < 0)    {       perror("socket");       exit(-1);    }     /*************************************************/    /* initialize socket address structure       */    /*************************************************/    memset(&addr, 0, sizeof(addr));    addr.sin_family      = af_inet;    addr.sin_addr.s_addr = inet_addr("10.0.0.1");    addr.sin_port        = htons(server_port);     /*************************************************/    /* connect server                         */    /*************************************************/    rc = connect(sockfd,                 (struct sockaddr *)&addr,                 sizeof(struct sockaddr_in));    if (rc < 0)    {       perror("connect");       close(sockfd);       exit(-1);    }    printf("connect completed.\n");    //ssl-ing connection     ssl = ssl_new(ctx);     bio *sbio;     sbio = bio_new(bio_s_socket());     bio_set_fd(sbio, sockfd, bio_close);     ssl_set_bio(ssl, sbio, sbio);     //ssl_ctx_set_verify_depth(ctx, 1);     //ssl_set_fd(ssl, sockfd);     printf("before ssl_connect: %d\n", result);     result = ssl_connect(ssl);     printf("ssl_connect: %d\n", result);      if(ssl_get_peer_certificate(ssl)!=null)     {           //check cert         //check_cert(ssl);         //getting ca certificate            //_ssl = ssl_new(ctx);         ssl_ctx_set_verify(ctx, ssl_verify_peer, null);           int result_long = ssl_get_verify_result(ssl);         printf("\ncertificate check result: %d", result_long);         if (ssl_get_verify_result(ssl) != x509_v_ok)             {                 printf("\ncertiticate verification failed\n");                 return 0;                 //exit(1);             }             else             {                 printf("\ncertiticate verification succeeded");             }      }      ssl_write(ssl, &ch, 1);     ssl_read(ssl, &ch, 1);     printf("char server = %c\n", ch);     ssl_shutdown(ssl);       /*************************************************/    /* close down socket                         */    /*************************************************/    close(sockfd); } 


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -