SSL_Connect sys call taking more time

2013-05-06 Thread Arjun SM
Hi all,

I have a daemon where I am trying to retrieve the common name from the
certificate during an HTTPS connection. What i am observing is that ,
SSL_Connect() function is taking more time to connect on some of the
websites.

I am trying on Mac OS X 10.8.3. Below is the code I have been using and I
am using non-blocking sockets


#include SSLUtil.h
#include sys/socket.h
#include sys/types.h
#include netinet/in.h
#include arpa/inet.h
#include strings.h
#include openssl/ssl.h
#include openssl/x509.h
#include openssl/crypto.h
#include errno.h
#include fcntl.h
#include string
#include Logging.h




bool SSLUtil::GetSSLServerNameFromIP(std::string ipAddress, std::string
serverName)
{
bool bRet = false;
int sock=-1;
MCLOG(SSLUtil::GetSSLServerNameFromIP Call for IP,ipAddress.c_str());
if(ConnectToServerAsync(ipAddress,443,sock))
{
if(RetrieveNameUsingSSL(sock,serverName))
{
bRet = true;
MCLOG(SSLUtil::GetSSLServerNameFromIP Call
return,ipAddress.c_str(),serverName.c_str());
}
else
{
MCLOG(SSLUtil::GetSSLServerNameFromIP RetrieveNameUsingSSL
call failed,ipAddress.c_str());
}

close(sock);
}else
{
MCLOG(SSLUtil::GetSSLServerNameFromIP connect asycn
failed,ipAddress.c_str());
}
return bRet;

}

#define TIMEOUT_SERVER 3 //seconds

bool SSLUtil::ConnectToServerAsync(std::string ipaddress, int port , int
sock)
{

//create the socket
sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock0)
{
//creating socket failed
MCLOG(SSLUtil::ConnectToServerAsync soceket creation failed );
return false;
}

//change socket options
int opts = fcntl(sock,F_GETFL);
if (opts  0) {
//pFailed F_GETFL
MCLOG(SSLUtil::ConnectToServerAsync F_GETFL failed );
return false;
}
opts = (opts | O_NONBLOCK);
if (fcntl(sock,F_SETFL,opts)  0) {
//Failed F_SETFL
MCLOG(SSLUtil::ConnectToServerAsync F_SETFL failed);
return false;
}

//make sure there is no error pending
int err = errno;
if (err  0)
{
MCLOG(SSLUtil::ConnectToServerAsync can't create non blocking
socket );
//printf(MakeConnectAttempt = can't set non-blocking socket);
if(sock)
{
close(sock);
}
return false;
}

struct sockaddr_in server_addr;
memset (server_addr, '\0', sizeof(server_addr));
server_addr.sin_family  = AF_INET;
server_addr.sin_port= htons(port);   /* Server Port number
*/
server_addr.sin_addr.s_addr = inet_addr(ipaddress.c_str()); /* Server
IP */
int status = connect(sock, (struct sockaddr*) server_addr,
sizeof(server_addr));


//wait for connection to succeed
if(status0)
{
status = errno;
if(status == EINPROGRESS)
{
MCLOG(SSLUtil::ConnectToServerAsync in progress ,
ipaddress.c_str());
if(!WaitOnSocket(sock,TIMEOUT_SERVER))
{
//printf(connect to %s failed\n,argv[1]);
MCLOG(SSLUtil::ConnectToServerAsync wait failed ,
ipaddress.c_str());
return false;
}

}else
{
//printf(connect to %s failed\n,argv[1]);
MCLOG(SSLUtil::ConnectToServerAsync connect failed , status);
return false;
}
}
MCLOG(SSLUtil::ConnectToServerAsync connect success , status);
return true;

}


bool SSLUtil::WaitOnSocket(int sockfd,int timeOutInSeconds)
{
fd_set readFDs;
fd_set writeFDs;
intselectResult;
// booltimeOut = false;

FD_ZERO(readFDs);
FD_ZERO(writeFDs);
FD_SET(sockfd, readFDs);
FD_SET(sockfd, writeFDs);
bool continueSelect ;
struct timeval waitd;

time_t seconds;
time_t future;
time_t now;

seconds = time(NULL);
future = seconds + timeOutInSeconds;
// waitd.tv_sec = timeOutInSeconds; // Make select wait up to 10
seconds for data
// waitd.tv_usec = 0; // and 0 milliseconds.

int err = 0;
continueSelect = true;
do
{
waitd.tv_sec = timeOutInSeconds; // Make select wait up to 5
seconds for data
waitd.tv_usec = 0; // and 0 milliseconds.

selectResult = select(sockfd+1, readFDs, writeFDs, NULL, waitd);
//printf(after select %d\n, selectResult);
err = errno;
if (selectResult  0)
{
for(int i=0;isockfd+1;i++)
{
if (FD_ISSET(i,readFDs))
{
continueSelect = false;
break;
}
if (FD_ISSET(i,writeFDs))
{
continueSelect = false;
break;
}
}
}
else
{
now = time(NULL);
if (now  future )
{
 

Re: SSL_Connect call gives SSL_ERROR_WANT_READ for non blocking sockets

2011-11-22 Thread Arjun SM
Ohh .. ok. But I just want the SSL_connect to succeed because I want to
fetch the certificate of an HTTPS website. So after the success of
SSL_connect() function, I would call SSL_get_peer_certificate().
Since I wait until the SSL_connect() function succeeds I wanted to know if
there is a better approach.

Hope I am able to convey my understandings for these functions. If you feel
that I dont, please help in understanding the same.

~Arjun

On Mon, Nov 21, 2011 at 8:10 PM, Michael S. Zick open...@morethan.orgwrote:

 On Mon November 21 2011, Arjun SM wrote:
  Well yes, these are not errors. My bad for naming the variable as
 'error'.
 

 Not my point -

 Your logic shows that you think the connection has failed when it has
 simple not yet finished with its protocol.

 Not finished because you didn't respond to the want-write and/or want-read.
 Something which your code must do when using non-blocking sockets.

 Mike
  ~Arjun
 
  On Thu, Nov 17, 2011 at 11:50 PM, Michael S. Zick open...@morethan.org
 wrote:
 
   On Thu November 17 2011, Arjun SM wrote:
Hi,
Thanks for the reply.
I have called the ssl_connect() function again after checking for
SSL_ERROR_WANT_READ
and SSL_ERROR_WANT_WRITE. But I wanted to know if I can optimize my
 code.
Below is my code
   
int counter = 6;
while (status  0  --counter 0 )
{
if(status  0)
{
error=SSL_get_error(ssl,status);
if(error == SSL_ERROR_WANT_READ || error ==
SSL_ERROR_WANT_WRITE)
{
MessageLog.Write(SSL 1st Connect error ,
   error);
   
  
   But these two cases are __not__ errors,
   you just need to 'read' or 'write' as indicated so the protocol can
   advance.
  
   Mike
usleep(200);
status = SSL_connect(ssl);
error=SSL_get_error(ssl,status);
MessageLog.Write(SSL 2nd Connect error ,
   error);
}
else
{
break;
}
}
} // end of while
   
I would try for some time and break out saying unable to connect. I
 am
   sure
I can optimize this code by using select() but I am unable to make it
   work.
If there is a better approach please do share.
   
~Arjun
   
On Tue, Nov 15, 2011 at 9:04 PM, Huaqing Wang whuaq...@gmail.com
   wrote:
   
 Hi, Arjun,

 For non-blocking case, you have to handle SSL_ERROR_WANT_READ  and
 SSL_ERROR_WANT_WRITE
 In that case you need to redo *SSL_connect.*
 *
 *
 Huaqing

 On Tue, Nov 15, 2011 at 5:51 AM, Arjun SM arjun...@gmail.com
 wrote:

 Hi all,
I am newbie to openssl any help is greatly appreciated.

 I have a requirement of fetching the Common name (domin name )
  from
   the
 certificate that I request from any HTTPS websites. I followed the
   regular
 method of

 1. establish a connection with the ip address using *connect()
 *system
 call.
 2. Use *SSL_connect()* system call to perform handshake.
 3. Use *SSL_get_peer_certificate()* to get the certificate.

 The problem I faced was that, the connect() call would at times
   return a
 errno 4 (EINTR) error . So i changed code from blocking to
   non-blocking
 sockets and used select() call to have a valid connection and
 return
   an
 appropriate file descriptor.
 Now the ssl_connect() call returns SSL_ERROR_WANT_READ
 or SSL_ERROR_WANT_WRITE error. I am unable to make my code work by
   adding a
 select() even on ssl_connect() call.

 If any one can please help as to how I need to use the
  ssl_connect()
   by
 polling that would be of great help. preferred language would be
 C/C++

 thanks,
 ~Arjun







 --
 Thank you.
 Best Regards,
 Michael(Huaqing) Wang


   
  
  
   __
   OpenSSL Project http://www.openssl.org
   User Support Mailing Listopenssl-users@openssl.org
   Automated List Manager   majord...@openssl.org
  
 


 __
 OpenSSL Project http://www.openssl.org
 User Support Mailing Listopenssl-users@openssl.org
 Automated List Manager   majord...@openssl.org



Re: SSL_Connect call gives SSL_ERROR_WANT_READ for non blocking sockets

2011-11-21 Thread Arjun SM
Well yes, these are not errors. My bad for naming the variable as 'error'.

~Arjun

On Thu, Nov 17, 2011 at 11:50 PM, Michael S. Zick open...@morethan.orgwrote:

 On Thu November 17 2011, Arjun SM wrote:
  Hi,
  Thanks for the reply.
  I have called the ssl_connect() function again after checking for
  SSL_ERROR_WANT_READ
  and SSL_ERROR_WANT_WRITE. But I wanted to know if I can optimize my code.
  Below is my code
 
  int counter = 6;
  while (status  0  --counter 0 )
  {
  if(status  0)
  {
  error=SSL_get_error(ssl,status);
  if(error == SSL_ERROR_WANT_READ || error ==
  SSL_ERROR_WANT_WRITE)
  {
  MessageLog.Write(SSL 1st Connect error ,
 error);
 

 But these two cases are __not__ errors,
 you just need to 'read' or 'write' as indicated so the protocol can
 advance.

 Mike
  usleep(200);
  status = SSL_connect(ssl);
  error=SSL_get_error(ssl,status);
  MessageLog.Write(SSL 2nd Connect error ,
 error);
  }
  else
  {
  break;
  }
  }
  } // end of while
 
  I would try for some time and break out saying unable to connect. I am
 sure
  I can optimize this code by using select() but I am unable to make it
 work.
  If there is a better approach please do share.
 
  ~Arjun
 
  On Tue, Nov 15, 2011 at 9:04 PM, Huaqing Wang whuaq...@gmail.com
 wrote:
 
   Hi, Arjun,
  
   For non-blocking case, you have to handle SSL_ERROR_WANT_READ  and
   SSL_ERROR_WANT_WRITE
   In that case you need to redo *SSL_connect.*
   *
   *
   Huaqing
  
   On Tue, Nov 15, 2011 at 5:51 AM, Arjun SM arjun...@gmail.com wrote:
  
   Hi all,
  I am newbie to openssl any help is greatly appreciated.
  
   I have a requirement of fetching the Common name (domin name )  from
 the
   certificate that I request from any HTTPS websites. I followed the
 regular
   method of
  
   1. establish a connection with the ip address using *connect() *system
   call.
   2. Use *SSL_connect()* system call to perform handshake.
   3. Use *SSL_get_peer_certificate()* to get the certificate.
  
   The problem I faced was that, the connect() call would at times
 return a
   errno 4 (EINTR) error . So i changed code from blocking to
 non-blocking
   sockets and used select() call to have a valid connection and return
 an
   appropriate file descriptor.
   Now the ssl_connect() call returns SSL_ERROR_WANT_READ
   or SSL_ERROR_WANT_WRITE error. I am unable to make my code work by
 adding a
   select() even on ssl_connect() call.
  
   If any one can please help as to how I need to use the  ssl_connect()
 by
   polling that would be of great help. preferred language would be C/C++
  
   thanks,
   ~Arjun
  
  
  
  
  
  
  
   --
   Thank you.
   Best Regards,
   Michael(Huaqing) Wang
  
  
 


 __
 OpenSSL Project http://www.openssl.org
 User Support Mailing Listopenssl-users@openssl.org
 Automated List Manager   majord...@openssl.org



Re: SSL_Connect call gives SSL_ERROR_WANT_READ for non blocking sockets

2011-11-17 Thread Arjun SM
Hi,
Thanks for the reply.
I have called the ssl_connect() function again after checking for
SSL_ERROR_WANT_READ
and SSL_ERROR_WANT_WRITE. But I wanted to know if I can optimize my code.
Below is my code

int counter = 6;
while (status  0  --counter 0 )
{
if(status  0)
{
error=SSL_get_error(ssl,status);
if(error == SSL_ERROR_WANT_READ || error ==
SSL_ERROR_WANT_WRITE)
{
MessageLog.Write(SSL 1st Connect error , error);
usleep(200);
status = SSL_connect(ssl);
error=SSL_get_error(ssl,status);
MessageLog.Write(SSL 2nd Connect error , error);
}
else
{
break;
}
}
} // end of while

I would try for some time and break out saying unable to connect. I am sure
I can optimize this code by using select() but I am unable to make it work.
If there is a better approach please do share.

~Arjun

On Tue, Nov 15, 2011 at 9:04 PM, Huaqing Wang whuaq...@gmail.com wrote:

 Hi, Arjun,

 For non-blocking case, you have to handle SSL_ERROR_WANT_READ  and
 SSL_ERROR_WANT_WRITE
 In that case you need to redo *SSL_connect.*
 *
 *
 Huaqing

 On Tue, Nov 15, 2011 at 5:51 AM, Arjun SM arjun...@gmail.com wrote:

 Hi all,
I am newbie to openssl any help is greatly appreciated.

 I have a requirement of fetching the Common name (domin name )  from the
 certificate that I request from any HTTPS websites. I followed the regular
 method of

 1. establish a connection with the ip address using *connect() *system
 call.
 2. Use *SSL_connect()* system call to perform handshake.
 3. Use *SSL_get_peer_certificate()* to get the certificate.

 The problem I faced was that, the connect() call would at times return a
 errno 4 (EINTR) error . So i changed code from blocking to non-blocking
 sockets and used select() call to have a valid connection and return an
 appropriate file descriptor.
 Now the ssl_connect() call returns SSL_ERROR_WANT_READ
 or SSL_ERROR_WANT_WRITE error. I am unable to make my code work by adding a
 select() even on ssl_connect() call.

 If any one can please help as to how I need to use the  ssl_connect() by
 polling that would be of great help. preferred language would be C/C++

 thanks,
 ~Arjun







 --
 Thank you.
 Best Regards,
 Michael(Huaqing) Wang




SSL_Connect call gives SSL_ERROR_WANT_READ for non blocking sockets

2011-11-15 Thread Arjun SM
Hi all,
   I am newbie to openssl any help is greatly appreciated.

I have a requirement of fetching the Common name (domin name )  from the
certificate that I request from any HTTPS websites. I followed the regular
method of

1. establish a connection with the ip address using *connect() *system call.
2. Use *SSL_connect()* system call to perform handshake.
3. Use *SSL_get_peer_certificate()* to get the certificate.

The problem I faced was that, the connect() call would at times return a
errno 4 (EINTR) error . So i changed code from blocking to non-blocking
sockets and used select() call to have a valid connection and return an
appropriate file descriptor.
Now the ssl_connect() call returns SSL_ERROR_WANT_READ
or SSL_ERROR_WANT_WRITE error. I am unable to make my code work by adding a
select() even on ssl_connect() call.

If any one can please help as to how I need to use the  ssl_connect() by
polling that would be of great help. preferred language would be C/C++

thanks,
~Arjun