SSL_connect() and SSL_accept() calls
I have been struggling with this for a few days now figuring out how they work. I have read the documentation and looked at some examples but I am still in need of guidance.
Specifically, when the client calls connect() and successfully connects to the server host, should I issue the SSL_connect() right after it to Initiate the handshake ? The client then tries to write some bytes to the socket using SSL_write().
On the other hand, the server uses pselect() to monitor any read fds ready for read and issues the accept() call successfully for the incoming connection. Should I issue the SSL_accept() call right after the accept() returns to complete the handshake ?
I have noticed that the SSL_connect() returns SSL_ERROR_WANT_READ (this is when the SSL_connect() is issued after a select() call to monitor the write fd set and returns and as per the Openssl documentation).
What is the right procedure here on issuing the calls and in what order ?
Edit to add snippet of code -
Client side :
err = connect(fd, addr, addrlen);
if ( err == -1 && errno == EINPROGRESS )
{
// check if this is a true error,
// or wait until connect times out
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sfd, &fdset);
timeval tv = {F_sockwaitconnect, 0}; TEMP_FAILURE_RETRY(err = select(fd + 1,
NULL,
&fdset,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
connect was successful
}
else
return 0;
const SSL_METHOD *method;
SSL_CTX *cctx;
SSL *cssl;
FILE *fp;
fp = stdout;
ERR_clear_error();
method = TLSv1_client_method();
cctx = SSL_CTX_new(method);
if ( cctx == NULL )
{
ERR_print_errors_fp(stdout);
return 0;
}
SSL_CTX_set_verify(cctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify_depth(cctx, 4);
if (SSL_CTX_load_verify_locations(cctx, "mycert.pem", NULL) == 0)
return 0;
SSL_CTX_set_options(cctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_COMPRESSION);
ERR_clear_error();
cssl = SSL_new(cctx); /* create new SSL connection state */
SSL_set_fd(cssl, fd); * attach the socket descriptor */
ERR_clear_error();
int rconnect = SSL_ERROR_WANT_READ;
while ( rconnect == SSL_ERROR_WANT_READ || rconnect == SSL_ERROR_WANT_WRITE )
{
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(cssl, rconnect), buf);
ERR_clear_error();
if ( rconnect == SSL_ERROR_WANT_READ ) {
int err = 0;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
timeval tv = {F_sockwaitconnect, 0};
TEMP_FAILURE_RETRY(err1 = select(fd + 1,
&fdset,
NULL,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
rconnect = SSL_connect(cssl);
}
}
}
X509 *cert;
cert = SSL_get_peer_certificate(cssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
ERR_clear_error();
r = SSL_write(cssl, buffer, len);
< check error >
Server side :
int res = pselect(max_fd + 1, // host socket file descriptor
&fd_setw, // set of ds wait 4 incoming data
NULL, // no write operations
NULL, // no exception operations
&tm, // how much time to wait
&sig_set); // block all signals
if ( event on listening socket )
{
client = accept(sfd, &peer, &peerl);
}
else // incoming data to receive on existing connection
{
SSL *ssl;
FILE *fp = stdout;
if ( !ctx )
{
return 0;
}
ERR_clear_error();
ssl = SSL_new(ctx);
SSL_set_fd(ssl, soc);
int ret = SSL_accept(ssl);
while (ret <= 0) {
ERR_print_errors_fp(fp);
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(ssl, ret), buf);
ERR_clear_error();
ret = SSL_accept(ssl);
}
X509 *cert;
cert = SSL_get_peer_certificate(ssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
// get data and analyze result
int rc = 0;
bool recv_called = false;
rc = SSL_read(ssl, buffer, len);
< check error >
}
Before all the above, the server opens, binds and listens on a non-blocking socket for any new incoming client connections.
When I run the above, the client does the connect() and the server does the accept().
The server is now waiting at pselect() for any fd's to be ready to receive data.
The client on the other hand is at the SSL_connect() and keeps getting the SSL_ERROR_WANT_READ error. The select() returns the socket is ready to read.
My guess is the client is waiting for the SSL_accept() part of the handshake ? I do not know why the server is waiting at pselect(). The code around SSL_accept() is wrong i.e it loops and does not look for the WANT_READ and WANT_WRITE errors but I do not get to that point in the code.
c++ c ssl encryption openssl
add a comment |
I have been struggling with this for a few days now figuring out how they work. I have read the documentation and looked at some examples but I am still in need of guidance.
Specifically, when the client calls connect() and successfully connects to the server host, should I issue the SSL_connect() right after it to Initiate the handshake ? The client then tries to write some bytes to the socket using SSL_write().
On the other hand, the server uses pselect() to monitor any read fds ready for read and issues the accept() call successfully for the incoming connection. Should I issue the SSL_accept() call right after the accept() returns to complete the handshake ?
I have noticed that the SSL_connect() returns SSL_ERROR_WANT_READ (this is when the SSL_connect() is issued after a select() call to monitor the write fd set and returns and as per the Openssl documentation).
What is the right procedure here on issuing the calls and in what order ?
Edit to add snippet of code -
Client side :
err = connect(fd, addr, addrlen);
if ( err == -1 && errno == EINPROGRESS )
{
// check if this is a true error,
// or wait until connect times out
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sfd, &fdset);
timeval tv = {F_sockwaitconnect, 0}; TEMP_FAILURE_RETRY(err = select(fd + 1,
NULL,
&fdset,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
connect was successful
}
else
return 0;
const SSL_METHOD *method;
SSL_CTX *cctx;
SSL *cssl;
FILE *fp;
fp = stdout;
ERR_clear_error();
method = TLSv1_client_method();
cctx = SSL_CTX_new(method);
if ( cctx == NULL )
{
ERR_print_errors_fp(stdout);
return 0;
}
SSL_CTX_set_verify(cctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify_depth(cctx, 4);
if (SSL_CTX_load_verify_locations(cctx, "mycert.pem", NULL) == 0)
return 0;
SSL_CTX_set_options(cctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_COMPRESSION);
ERR_clear_error();
cssl = SSL_new(cctx); /* create new SSL connection state */
SSL_set_fd(cssl, fd); * attach the socket descriptor */
ERR_clear_error();
int rconnect = SSL_ERROR_WANT_READ;
while ( rconnect == SSL_ERROR_WANT_READ || rconnect == SSL_ERROR_WANT_WRITE )
{
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(cssl, rconnect), buf);
ERR_clear_error();
if ( rconnect == SSL_ERROR_WANT_READ ) {
int err = 0;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
timeval tv = {F_sockwaitconnect, 0};
TEMP_FAILURE_RETRY(err1 = select(fd + 1,
&fdset,
NULL,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
rconnect = SSL_connect(cssl);
}
}
}
X509 *cert;
cert = SSL_get_peer_certificate(cssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
ERR_clear_error();
r = SSL_write(cssl, buffer, len);
< check error >
Server side :
int res = pselect(max_fd + 1, // host socket file descriptor
&fd_setw, // set of ds wait 4 incoming data
NULL, // no write operations
NULL, // no exception operations
&tm, // how much time to wait
&sig_set); // block all signals
if ( event on listening socket )
{
client = accept(sfd, &peer, &peerl);
}
else // incoming data to receive on existing connection
{
SSL *ssl;
FILE *fp = stdout;
if ( !ctx )
{
return 0;
}
ERR_clear_error();
ssl = SSL_new(ctx);
SSL_set_fd(ssl, soc);
int ret = SSL_accept(ssl);
while (ret <= 0) {
ERR_print_errors_fp(fp);
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(ssl, ret), buf);
ERR_clear_error();
ret = SSL_accept(ssl);
}
X509 *cert;
cert = SSL_get_peer_certificate(ssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
// get data and analyze result
int rc = 0;
bool recv_called = false;
rc = SSL_read(ssl, buffer, len);
< check error >
}
Before all the above, the server opens, binds and listens on a non-blocking socket for any new incoming client connections.
When I run the above, the client does the connect() and the server does the accept().
The server is now waiting at pselect() for any fd's to be ready to receive data.
The client on the other hand is at the SSL_connect() and keeps getting the SSL_ERROR_WANT_READ error. The select() returns the socket is ready to read.
My guess is the client is waiting for the SSL_accept() part of the handshake ? I do not know why the server is waiting at pselect(). The code around SSL_accept() is wrong i.e it loops and does not look for the WANT_READ and WANT_WRITE errors but I do not get to that point in the code.
c++ c ssl encryption openssl
is your client code synchronous or asynchronous?
– Richard Hodges
Nov 24 '18 at 6:10
@RichardHodges All the sockets are non-blocking. The client writes out all the I/O vectors 1 by 1 in a loop and can come back later if not all data was written. Does that answer your question ?
– PeterJ
Nov 24 '18 at 6:20
add a comment |
I have been struggling with this for a few days now figuring out how they work. I have read the documentation and looked at some examples but I am still in need of guidance.
Specifically, when the client calls connect() and successfully connects to the server host, should I issue the SSL_connect() right after it to Initiate the handshake ? The client then tries to write some bytes to the socket using SSL_write().
On the other hand, the server uses pselect() to monitor any read fds ready for read and issues the accept() call successfully for the incoming connection. Should I issue the SSL_accept() call right after the accept() returns to complete the handshake ?
I have noticed that the SSL_connect() returns SSL_ERROR_WANT_READ (this is when the SSL_connect() is issued after a select() call to monitor the write fd set and returns and as per the Openssl documentation).
What is the right procedure here on issuing the calls and in what order ?
Edit to add snippet of code -
Client side :
err = connect(fd, addr, addrlen);
if ( err == -1 && errno == EINPROGRESS )
{
// check if this is a true error,
// or wait until connect times out
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sfd, &fdset);
timeval tv = {F_sockwaitconnect, 0}; TEMP_FAILURE_RETRY(err = select(fd + 1,
NULL,
&fdset,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
connect was successful
}
else
return 0;
const SSL_METHOD *method;
SSL_CTX *cctx;
SSL *cssl;
FILE *fp;
fp = stdout;
ERR_clear_error();
method = TLSv1_client_method();
cctx = SSL_CTX_new(method);
if ( cctx == NULL )
{
ERR_print_errors_fp(stdout);
return 0;
}
SSL_CTX_set_verify(cctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify_depth(cctx, 4);
if (SSL_CTX_load_verify_locations(cctx, "mycert.pem", NULL) == 0)
return 0;
SSL_CTX_set_options(cctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_COMPRESSION);
ERR_clear_error();
cssl = SSL_new(cctx); /* create new SSL connection state */
SSL_set_fd(cssl, fd); * attach the socket descriptor */
ERR_clear_error();
int rconnect = SSL_ERROR_WANT_READ;
while ( rconnect == SSL_ERROR_WANT_READ || rconnect == SSL_ERROR_WANT_WRITE )
{
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(cssl, rconnect), buf);
ERR_clear_error();
if ( rconnect == SSL_ERROR_WANT_READ ) {
int err = 0;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
timeval tv = {F_sockwaitconnect, 0};
TEMP_FAILURE_RETRY(err1 = select(fd + 1,
&fdset,
NULL,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
rconnect = SSL_connect(cssl);
}
}
}
X509 *cert;
cert = SSL_get_peer_certificate(cssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
ERR_clear_error();
r = SSL_write(cssl, buffer, len);
< check error >
Server side :
int res = pselect(max_fd + 1, // host socket file descriptor
&fd_setw, // set of ds wait 4 incoming data
NULL, // no write operations
NULL, // no exception operations
&tm, // how much time to wait
&sig_set); // block all signals
if ( event on listening socket )
{
client = accept(sfd, &peer, &peerl);
}
else // incoming data to receive on existing connection
{
SSL *ssl;
FILE *fp = stdout;
if ( !ctx )
{
return 0;
}
ERR_clear_error();
ssl = SSL_new(ctx);
SSL_set_fd(ssl, soc);
int ret = SSL_accept(ssl);
while (ret <= 0) {
ERR_print_errors_fp(fp);
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(ssl, ret), buf);
ERR_clear_error();
ret = SSL_accept(ssl);
}
X509 *cert;
cert = SSL_get_peer_certificate(ssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
// get data and analyze result
int rc = 0;
bool recv_called = false;
rc = SSL_read(ssl, buffer, len);
< check error >
}
Before all the above, the server opens, binds and listens on a non-blocking socket for any new incoming client connections.
When I run the above, the client does the connect() and the server does the accept().
The server is now waiting at pselect() for any fd's to be ready to receive data.
The client on the other hand is at the SSL_connect() and keeps getting the SSL_ERROR_WANT_READ error. The select() returns the socket is ready to read.
My guess is the client is waiting for the SSL_accept() part of the handshake ? I do not know why the server is waiting at pselect(). The code around SSL_accept() is wrong i.e it loops and does not look for the WANT_READ and WANT_WRITE errors but I do not get to that point in the code.
c++ c ssl encryption openssl
I have been struggling with this for a few days now figuring out how they work. I have read the documentation and looked at some examples but I am still in need of guidance.
Specifically, when the client calls connect() and successfully connects to the server host, should I issue the SSL_connect() right after it to Initiate the handshake ? The client then tries to write some bytes to the socket using SSL_write().
On the other hand, the server uses pselect() to monitor any read fds ready for read and issues the accept() call successfully for the incoming connection. Should I issue the SSL_accept() call right after the accept() returns to complete the handshake ?
I have noticed that the SSL_connect() returns SSL_ERROR_WANT_READ (this is when the SSL_connect() is issued after a select() call to monitor the write fd set and returns and as per the Openssl documentation).
What is the right procedure here on issuing the calls and in what order ?
Edit to add snippet of code -
Client side :
err = connect(fd, addr, addrlen);
if ( err == -1 && errno == EINPROGRESS )
{
// check if this is a true error,
// or wait until connect times out
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sfd, &fdset);
timeval tv = {F_sockwaitconnect, 0}; TEMP_FAILURE_RETRY(err = select(fd + 1,
NULL,
&fdset,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
connect was successful
}
else
return 0;
const SSL_METHOD *method;
SSL_CTX *cctx;
SSL *cssl;
FILE *fp;
fp = stdout;
ERR_clear_error();
method = TLSv1_client_method();
cctx = SSL_CTX_new(method);
if ( cctx == NULL )
{
ERR_print_errors_fp(stdout);
return 0;
}
SSL_CTX_set_verify(cctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify_depth(cctx, 4);
if (SSL_CTX_load_verify_locations(cctx, "mycert.pem", NULL) == 0)
return 0;
SSL_CTX_set_options(cctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_COMPRESSION);
ERR_clear_error();
cssl = SSL_new(cctx); /* create new SSL connection state */
SSL_set_fd(cssl, fd); * attach the socket descriptor */
ERR_clear_error();
int rconnect = SSL_ERROR_WANT_READ;
while ( rconnect == SSL_ERROR_WANT_READ || rconnect == SSL_ERROR_WANT_WRITE )
{
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(cssl, rconnect), buf);
ERR_clear_error();
if ( rconnect == SSL_ERROR_WANT_READ ) {
int err = 0;
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
timeval tv = {F_sockwaitconnect, 0};
TEMP_FAILURE_RETRY(err1 = select(fd + 1,
&fdset,
NULL,
NULL,
&tv));
// what happened?
if ( err == 1 )
{
rconnect = SSL_connect(cssl);
}
}
}
X509 *cert;
cert = SSL_get_peer_certificate(cssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
ERR_clear_error();
r = SSL_write(cssl, buffer, len);
< check error >
Server side :
int res = pselect(max_fd + 1, // host socket file descriptor
&fd_setw, // set of ds wait 4 incoming data
NULL, // no write operations
NULL, // no exception operations
&tm, // how much time to wait
&sig_set); // block all signals
if ( event on listening socket )
{
client = accept(sfd, &peer, &peerl);
}
else // incoming data to receive on existing connection
{
SSL *ssl;
FILE *fp = stdout;
if ( !ctx )
{
return 0;
}
ERR_clear_error();
ssl = SSL_new(ctx);
SSL_set_fd(ssl, soc);
int ret = SSL_accept(ssl);
while (ret <= 0) {
ERR_print_errors_fp(fp);
char *buf = (char *) malloc(124);
ERR_error_string(SSL_get_error(ssl, ret), buf);
ERR_clear_error();
ret = SSL_accept(ssl);
}
X509 *cert;
cert = SSL_get_peer_certificate(ssl);
char line[2000+1];
if ( cert != NULL )
{
X509_NAME_oneline(X509_get_subject_name(cert), line, MAX_SIZE);
X509_NAME_oneline(X509_get_issuer_name(cert), line1, MAX_SIZE);
X509_free(cert);
}
// get data and analyze result
int rc = 0;
bool recv_called = false;
rc = SSL_read(ssl, buffer, len);
< check error >
}
Before all the above, the server opens, binds and listens on a non-blocking socket for any new incoming client connections.
When I run the above, the client does the connect() and the server does the accept().
The server is now waiting at pselect() for any fd's to be ready to receive data.
The client on the other hand is at the SSL_connect() and keeps getting the SSL_ERROR_WANT_READ error. The select() returns the socket is ready to read.
My guess is the client is waiting for the SSL_accept() part of the handshake ? I do not know why the server is waiting at pselect(). The code around SSL_accept() is wrong i.e it loops and does not look for the WANT_READ and WANT_WRITE errors but I do not get to that point in the code.
c++ c ssl encryption openssl
c++ c ssl encryption openssl
edited Nov 24 '18 at 21:02
PeterJ
asked Nov 24 '18 at 6:01
PeterJPeterJ
54
54
is your client code synchronous or asynchronous?
– Richard Hodges
Nov 24 '18 at 6:10
@RichardHodges All the sockets are non-blocking. The client writes out all the I/O vectors 1 by 1 in a loop and can come back later if not all data was written. Does that answer your question ?
– PeterJ
Nov 24 '18 at 6:20
add a comment |
is your client code synchronous or asynchronous?
– Richard Hodges
Nov 24 '18 at 6:10
@RichardHodges All the sockets are non-blocking. The client writes out all the I/O vectors 1 by 1 in a loop and can come back later if not all data was written. Does that answer your question ?
– PeterJ
Nov 24 '18 at 6:20
is your client code synchronous or asynchronous?
– Richard Hodges
Nov 24 '18 at 6:10
is your client code synchronous or asynchronous?
– Richard Hodges
Nov 24 '18 at 6:10
@RichardHodges All the sockets are non-blocking. The client writes out all the I/O vectors 1 by 1 in a loop and can come back later if not all data was written. Does that answer your question ?
– PeterJ
Nov 24 '18 at 6:20
@RichardHodges All the sockets are non-blocking. The client writes out all the I/O vectors 1 by 1 in a loop and can come back later if not all data was written. Does that answer your question ?
– PeterJ
Nov 24 '18 at 6:20
add a comment |
1 Answer
1
active
oldest
votes
SSL_connect can be called whenever the connect is finished. Since both connect and SSL_connect need to exchange data with the peer they might not succeed immediately when using non-blocking sockets. If SSL_connect returns with an error of SSL_WANT_READ or SSL_WANT_WRITE you have to call it again after new data got available on the socket (SSL_WANT_READ) or the socket is writable (SSL_WANT_WRITE). You can check or wait for this with select, pselect, poll, epoll, kqueue or whatever API your OS provides for this.
SSL_accept and accept are similar, i.e. SSL_accept can be called directly after a successful accept, might not succeed immediately since data exchange is needed with the SSL client and thus you have to call it again if it returns an error of SSL_WANT_READ or SSL_WANT_WRITE.
Note that SSL_write and SSL_read might also result in such errors. i.e. you need to deal with SSL_WANT_READ and SSL_WANT_WRITE also for these functions and also the same way as with SSL_connect and SSL_accept. It might even be that a SSL_read results in a SSL_WANT_WRITE since a SSL renegotiation might happen even if the SSL session was already established.
Thanks. The client does the connect() and issues a select() if the connect is not successful to wait for the socket to be writable. Once that succeeds, I issue the SSL_connect() call. This returns back with SSL_ERROR_WANT_READ. At this point the socket is writable but for some reason the SSL_connect() returns back a WANT_READ error. I am not sure why. At first guess I thought it was because the SSL_accept() call should have happened by now to complete the handshake. Is that true ? If so, should I loop in client around the SSL_connect() till the SSL_accept() finishes ?
– PeterJ
Nov 24 '18 at 6:45
@PeterJ: As I said, bothSSL_connectandSSL_acceptneed to exchange data with the peer. This is not only send some data but actually receive data too - have a look at how the SSL handshake works. Given that you are using non-blocking sockets theSSL_connectwill not (blocking) wait for the server to reply but give youSSL_WANT_READso you can call it again once the server has send the reply back.
– Steffen Ullrich
Nov 24 '18 at 6:59
@PeterJ: "...should I loop ..."* - the main point of using non-blocking sockets is to do other things in the mean time. If you don't want to do this use blocking sockets instead. Busy looping is just wasting resources, i.e. is much worse then just using a blocking socket where the OS kernel can deal with other things until the peer replies. If you use non-blocking sockets to have control over timeouts useselector similar to wait for the socket readable (in case ofSSL_WANT_READ) and use a timeout for this function - but don't just blindly retry again and again inside a loop.
– Steffen Ullrich
Nov 24 '18 at 7:03
I changed the code a bit. Once the client does the connect() and the server accept() the connection, the client needs to send a few bytes over. Before the SSL_write(), I do a SSL_connect() and get the WANT_READ error. I do select() to wait for the fd to be readable. This hangs! The server on the other hand is waiting on pselect() to wait for any fd's to be ready to recv the bytes which will only happen after the client sends them. Then the code would do the SSL_accept() to complete the handshake and then SSL_read(). I am doing something wrong in the server code and not getting to SSL_accept()
– PeterJ
Nov 24 '18 at 9:02
Per the picture you shared, does the SSL_ERROR_WANT_READ error on SSL_connect() suggest that the client is waiting for the server to send over the handshake details (via SSL_accept() ) ?
– PeterJ
Nov 24 '18 at 9:09
|
show 14 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53455592%2fssl-connect-and-ssl-accept-calls%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
SSL_connect can be called whenever the connect is finished. Since both connect and SSL_connect need to exchange data with the peer they might not succeed immediately when using non-blocking sockets. If SSL_connect returns with an error of SSL_WANT_READ or SSL_WANT_WRITE you have to call it again after new data got available on the socket (SSL_WANT_READ) or the socket is writable (SSL_WANT_WRITE). You can check or wait for this with select, pselect, poll, epoll, kqueue or whatever API your OS provides for this.
SSL_accept and accept are similar, i.e. SSL_accept can be called directly after a successful accept, might not succeed immediately since data exchange is needed with the SSL client and thus you have to call it again if it returns an error of SSL_WANT_READ or SSL_WANT_WRITE.
Note that SSL_write and SSL_read might also result in such errors. i.e. you need to deal with SSL_WANT_READ and SSL_WANT_WRITE also for these functions and also the same way as with SSL_connect and SSL_accept. It might even be that a SSL_read results in a SSL_WANT_WRITE since a SSL renegotiation might happen even if the SSL session was already established.
Thanks. The client does the connect() and issues a select() if the connect is not successful to wait for the socket to be writable. Once that succeeds, I issue the SSL_connect() call. This returns back with SSL_ERROR_WANT_READ. At this point the socket is writable but for some reason the SSL_connect() returns back a WANT_READ error. I am not sure why. At first guess I thought it was because the SSL_accept() call should have happened by now to complete the handshake. Is that true ? If so, should I loop in client around the SSL_connect() till the SSL_accept() finishes ?
– PeterJ
Nov 24 '18 at 6:45
@PeterJ: As I said, bothSSL_connectandSSL_acceptneed to exchange data with the peer. This is not only send some data but actually receive data too - have a look at how the SSL handshake works. Given that you are using non-blocking sockets theSSL_connectwill not (blocking) wait for the server to reply but give youSSL_WANT_READso you can call it again once the server has send the reply back.
– Steffen Ullrich
Nov 24 '18 at 6:59
@PeterJ: "...should I loop ..."* - the main point of using non-blocking sockets is to do other things in the mean time. If you don't want to do this use blocking sockets instead. Busy looping is just wasting resources, i.e. is much worse then just using a blocking socket where the OS kernel can deal with other things until the peer replies. If you use non-blocking sockets to have control over timeouts useselector similar to wait for the socket readable (in case ofSSL_WANT_READ) and use a timeout for this function - but don't just blindly retry again and again inside a loop.
– Steffen Ullrich
Nov 24 '18 at 7:03
I changed the code a bit. Once the client does the connect() and the server accept() the connection, the client needs to send a few bytes over. Before the SSL_write(), I do a SSL_connect() and get the WANT_READ error. I do select() to wait for the fd to be readable. This hangs! The server on the other hand is waiting on pselect() to wait for any fd's to be ready to recv the bytes which will only happen after the client sends them. Then the code would do the SSL_accept() to complete the handshake and then SSL_read(). I am doing something wrong in the server code and not getting to SSL_accept()
– PeterJ
Nov 24 '18 at 9:02
Per the picture you shared, does the SSL_ERROR_WANT_READ error on SSL_connect() suggest that the client is waiting for the server to send over the handshake details (via SSL_accept() ) ?
– PeterJ
Nov 24 '18 at 9:09
|
show 14 more comments
SSL_connect can be called whenever the connect is finished. Since both connect and SSL_connect need to exchange data with the peer they might not succeed immediately when using non-blocking sockets. If SSL_connect returns with an error of SSL_WANT_READ or SSL_WANT_WRITE you have to call it again after new data got available on the socket (SSL_WANT_READ) or the socket is writable (SSL_WANT_WRITE). You can check or wait for this with select, pselect, poll, epoll, kqueue or whatever API your OS provides for this.
SSL_accept and accept are similar, i.e. SSL_accept can be called directly after a successful accept, might not succeed immediately since data exchange is needed with the SSL client and thus you have to call it again if it returns an error of SSL_WANT_READ or SSL_WANT_WRITE.
Note that SSL_write and SSL_read might also result in such errors. i.e. you need to deal with SSL_WANT_READ and SSL_WANT_WRITE also for these functions and also the same way as with SSL_connect and SSL_accept. It might even be that a SSL_read results in a SSL_WANT_WRITE since a SSL renegotiation might happen even if the SSL session was already established.
Thanks. The client does the connect() and issues a select() if the connect is not successful to wait for the socket to be writable. Once that succeeds, I issue the SSL_connect() call. This returns back with SSL_ERROR_WANT_READ. At this point the socket is writable but for some reason the SSL_connect() returns back a WANT_READ error. I am not sure why. At first guess I thought it was because the SSL_accept() call should have happened by now to complete the handshake. Is that true ? If so, should I loop in client around the SSL_connect() till the SSL_accept() finishes ?
– PeterJ
Nov 24 '18 at 6:45
@PeterJ: As I said, bothSSL_connectandSSL_acceptneed to exchange data with the peer. This is not only send some data but actually receive data too - have a look at how the SSL handshake works. Given that you are using non-blocking sockets theSSL_connectwill not (blocking) wait for the server to reply but give youSSL_WANT_READso you can call it again once the server has send the reply back.
– Steffen Ullrich
Nov 24 '18 at 6:59
@PeterJ: "...should I loop ..."* - the main point of using non-blocking sockets is to do other things in the mean time. If you don't want to do this use blocking sockets instead. Busy looping is just wasting resources, i.e. is much worse then just using a blocking socket where the OS kernel can deal with other things until the peer replies. If you use non-blocking sockets to have control over timeouts useselector similar to wait for the socket readable (in case ofSSL_WANT_READ) and use a timeout for this function - but don't just blindly retry again and again inside a loop.
– Steffen Ullrich
Nov 24 '18 at 7:03
I changed the code a bit. Once the client does the connect() and the server accept() the connection, the client needs to send a few bytes over. Before the SSL_write(), I do a SSL_connect() and get the WANT_READ error. I do select() to wait for the fd to be readable. This hangs! The server on the other hand is waiting on pselect() to wait for any fd's to be ready to recv the bytes which will only happen after the client sends them. Then the code would do the SSL_accept() to complete the handshake and then SSL_read(). I am doing something wrong in the server code and not getting to SSL_accept()
– PeterJ
Nov 24 '18 at 9:02
Per the picture you shared, does the SSL_ERROR_WANT_READ error on SSL_connect() suggest that the client is waiting for the server to send over the handshake details (via SSL_accept() ) ?
– PeterJ
Nov 24 '18 at 9:09
|
show 14 more comments
SSL_connect can be called whenever the connect is finished. Since both connect and SSL_connect need to exchange data with the peer they might not succeed immediately when using non-blocking sockets. If SSL_connect returns with an error of SSL_WANT_READ or SSL_WANT_WRITE you have to call it again after new data got available on the socket (SSL_WANT_READ) or the socket is writable (SSL_WANT_WRITE). You can check or wait for this with select, pselect, poll, epoll, kqueue or whatever API your OS provides for this.
SSL_accept and accept are similar, i.e. SSL_accept can be called directly after a successful accept, might not succeed immediately since data exchange is needed with the SSL client and thus you have to call it again if it returns an error of SSL_WANT_READ or SSL_WANT_WRITE.
Note that SSL_write and SSL_read might also result in such errors. i.e. you need to deal with SSL_WANT_READ and SSL_WANT_WRITE also for these functions and also the same way as with SSL_connect and SSL_accept. It might even be that a SSL_read results in a SSL_WANT_WRITE since a SSL renegotiation might happen even if the SSL session was already established.
SSL_connect can be called whenever the connect is finished. Since both connect and SSL_connect need to exchange data with the peer they might not succeed immediately when using non-blocking sockets. If SSL_connect returns with an error of SSL_WANT_READ or SSL_WANT_WRITE you have to call it again after new data got available on the socket (SSL_WANT_READ) or the socket is writable (SSL_WANT_WRITE). You can check or wait for this with select, pselect, poll, epoll, kqueue or whatever API your OS provides for this.
SSL_accept and accept are similar, i.e. SSL_accept can be called directly after a successful accept, might not succeed immediately since data exchange is needed with the SSL client and thus you have to call it again if it returns an error of SSL_WANT_READ or SSL_WANT_WRITE.
Note that SSL_write and SSL_read might also result in such errors. i.e. you need to deal with SSL_WANT_READ and SSL_WANT_WRITE also for these functions and also the same way as with SSL_connect and SSL_accept. It might even be that a SSL_read results in a SSL_WANT_WRITE since a SSL renegotiation might happen even if the SSL session was already established.
edited Nov 24 '18 at 16:56
James K Polk
30.1k116896
30.1k116896
answered Nov 24 '18 at 6:35
Steffen UllrichSteffen Ullrich
61.1k35899
61.1k35899
Thanks. The client does the connect() and issues a select() if the connect is not successful to wait for the socket to be writable. Once that succeeds, I issue the SSL_connect() call. This returns back with SSL_ERROR_WANT_READ. At this point the socket is writable but for some reason the SSL_connect() returns back a WANT_READ error. I am not sure why. At first guess I thought it was because the SSL_accept() call should have happened by now to complete the handshake. Is that true ? If so, should I loop in client around the SSL_connect() till the SSL_accept() finishes ?
– PeterJ
Nov 24 '18 at 6:45
@PeterJ: As I said, bothSSL_connectandSSL_acceptneed to exchange data with the peer. This is not only send some data but actually receive data too - have a look at how the SSL handshake works. Given that you are using non-blocking sockets theSSL_connectwill not (blocking) wait for the server to reply but give youSSL_WANT_READso you can call it again once the server has send the reply back.
– Steffen Ullrich
Nov 24 '18 at 6:59
@PeterJ: "...should I loop ..."* - the main point of using non-blocking sockets is to do other things in the mean time. If you don't want to do this use blocking sockets instead. Busy looping is just wasting resources, i.e. is much worse then just using a blocking socket where the OS kernel can deal with other things until the peer replies. If you use non-blocking sockets to have control over timeouts useselector similar to wait for the socket readable (in case ofSSL_WANT_READ) and use a timeout for this function - but don't just blindly retry again and again inside a loop.
– Steffen Ullrich
Nov 24 '18 at 7:03
I changed the code a bit. Once the client does the connect() and the server accept() the connection, the client needs to send a few bytes over. Before the SSL_write(), I do a SSL_connect() and get the WANT_READ error. I do select() to wait for the fd to be readable. This hangs! The server on the other hand is waiting on pselect() to wait for any fd's to be ready to recv the bytes which will only happen after the client sends them. Then the code would do the SSL_accept() to complete the handshake and then SSL_read(). I am doing something wrong in the server code and not getting to SSL_accept()
– PeterJ
Nov 24 '18 at 9:02
Per the picture you shared, does the SSL_ERROR_WANT_READ error on SSL_connect() suggest that the client is waiting for the server to send over the handshake details (via SSL_accept() ) ?
– PeterJ
Nov 24 '18 at 9:09
|
show 14 more comments
Thanks. The client does the connect() and issues a select() if the connect is not successful to wait for the socket to be writable. Once that succeeds, I issue the SSL_connect() call. This returns back with SSL_ERROR_WANT_READ. At this point the socket is writable but for some reason the SSL_connect() returns back a WANT_READ error. I am not sure why. At first guess I thought it was because the SSL_accept() call should have happened by now to complete the handshake. Is that true ? If so, should I loop in client around the SSL_connect() till the SSL_accept() finishes ?
– PeterJ
Nov 24 '18 at 6:45
@PeterJ: As I said, bothSSL_connectandSSL_acceptneed to exchange data with the peer. This is not only send some data but actually receive data too - have a look at how the SSL handshake works. Given that you are using non-blocking sockets theSSL_connectwill not (blocking) wait for the server to reply but give youSSL_WANT_READso you can call it again once the server has send the reply back.
– Steffen Ullrich
Nov 24 '18 at 6:59
@PeterJ: "...should I loop ..."* - the main point of using non-blocking sockets is to do other things in the mean time. If you don't want to do this use blocking sockets instead. Busy looping is just wasting resources, i.e. is much worse then just using a blocking socket where the OS kernel can deal with other things until the peer replies. If you use non-blocking sockets to have control over timeouts useselector similar to wait for the socket readable (in case ofSSL_WANT_READ) and use a timeout for this function - but don't just blindly retry again and again inside a loop.
– Steffen Ullrich
Nov 24 '18 at 7:03
I changed the code a bit. Once the client does the connect() and the server accept() the connection, the client needs to send a few bytes over. Before the SSL_write(), I do a SSL_connect() and get the WANT_READ error. I do select() to wait for the fd to be readable. This hangs! The server on the other hand is waiting on pselect() to wait for any fd's to be ready to recv the bytes which will only happen after the client sends them. Then the code would do the SSL_accept() to complete the handshake and then SSL_read(). I am doing something wrong in the server code and not getting to SSL_accept()
– PeterJ
Nov 24 '18 at 9:02
Per the picture you shared, does the SSL_ERROR_WANT_READ error on SSL_connect() suggest that the client is waiting for the server to send over the handshake details (via SSL_accept() ) ?
– PeterJ
Nov 24 '18 at 9:09
Thanks. The client does the connect() and issues a select() if the connect is not successful to wait for the socket to be writable. Once that succeeds, I issue the SSL_connect() call. This returns back with SSL_ERROR_WANT_READ. At this point the socket is writable but for some reason the SSL_connect() returns back a WANT_READ error. I am not sure why. At first guess I thought it was because the SSL_accept() call should have happened by now to complete the handshake. Is that true ? If so, should I loop in client around the SSL_connect() till the SSL_accept() finishes ?
– PeterJ
Nov 24 '18 at 6:45
Thanks. The client does the connect() and issues a select() if the connect is not successful to wait for the socket to be writable. Once that succeeds, I issue the SSL_connect() call. This returns back with SSL_ERROR_WANT_READ. At this point the socket is writable but for some reason the SSL_connect() returns back a WANT_READ error. I am not sure why. At first guess I thought it was because the SSL_accept() call should have happened by now to complete the handshake. Is that true ? If so, should I loop in client around the SSL_connect() till the SSL_accept() finishes ?
– PeterJ
Nov 24 '18 at 6:45
@PeterJ: As I said, both
SSL_connect and SSL_accept need to exchange data with the peer. This is not only send some data but actually receive data too - have a look at how the SSL handshake works. Given that you are using non-blocking sockets the SSL_connect will not (blocking) wait for the server to reply but give you SSL_WANT_READ so you can call it again once the server has send the reply back.– Steffen Ullrich
Nov 24 '18 at 6:59
@PeterJ: As I said, both
SSL_connect and SSL_accept need to exchange data with the peer. This is not only send some data but actually receive data too - have a look at how the SSL handshake works. Given that you are using non-blocking sockets the SSL_connect will not (blocking) wait for the server to reply but give you SSL_WANT_READ so you can call it again once the server has send the reply back.– Steffen Ullrich
Nov 24 '18 at 6:59
@PeterJ: "...should I loop ..."* - the main point of using non-blocking sockets is to do other things in the mean time. If you don't want to do this use blocking sockets instead. Busy looping is just wasting resources, i.e. is much worse then just using a blocking socket where the OS kernel can deal with other things until the peer replies. If you use non-blocking sockets to have control over timeouts use
select or similar to wait for the socket readable (in case of SSL_WANT_READ) and use a timeout for this function - but don't just blindly retry again and again inside a loop.– Steffen Ullrich
Nov 24 '18 at 7:03
@PeterJ: "...should I loop ..."* - the main point of using non-blocking sockets is to do other things in the mean time. If you don't want to do this use blocking sockets instead. Busy looping is just wasting resources, i.e. is much worse then just using a blocking socket where the OS kernel can deal with other things until the peer replies. If you use non-blocking sockets to have control over timeouts use
select or similar to wait for the socket readable (in case of SSL_WANT_READ) and use a timeout for this function - but don't just blindly retry again and again inside a loop.– Steffen Ullrich
Nov 24 '18 at 7:03
I changed the code a bit. Once the client does the connect() and the server accept() the connection, the client needs to send a few bytes over. Before the SSL_write(), I do a SSL_connect() and get the WANT_READ error. I do select() to wait for the fd to be readable. This hangs! The server on the other hand is waiting on pselect() to wait for any fd's to be ready to recv the bytes which will only happen after the client sends them. Then the code would do the SSL_accept() to complete the handshake and then SSL_read(). I am doing something wrong in the server code and not getting to SSL_accept()
– PeterJ
Nov 24 '18 at 9:02
I changed the code a bit. Once the client does the connect() and the server accept() the connection, the client needs to send a few bytes over. Before the SSL_write(), I do a SSL_connect() and get the WANT_READ error. I do select() to wait for the fd to be readable. This hangs! The server on the other hand is waiting on pselect() to wait for any fd's to be ready to recv the bytes which will only happen after the client sends them. Then the code would do the SSL_accept() to complete the handshake and then SSL_read(). I am doing something wrong in the server code and not getting to SSL_accept()
– PeterJ
Nov 24 '18 at 9:02
Per the picture you shared, does the SSL_ERROR_WANT_READ error on SSL_connect() suggest that the client is waiting for the server to send over the handshake details (via SSL_accept() ) ?
– PeterJ
Nov 24 '18 at 9:09
Per the picture you shared, does the SSL_ERROR_WANT_READ error on SSL_connect() suggest that the client is waiting for the server to send over the handshake details (via SSL_accept() ) ?
– PeterJ
Nov 24 '18 at 9:09
|
show 14 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53455592%2fssl-connect-and-ssl-accept-calls%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
is your client code synchronous or asynchronous?
– Richard Hodges
Nov 24 '18 at 6:10
@RichardHodges All the sockets are non-blocking. The client writes out all the I/O vectors 1 by 1 in a loop and can come back later if not all data was written. Does that answer your question ?
– PeterJ
Nov 24 '18 at 6:20