Make non blocking I/O work for accept BIOs.
diff --git a/CHANGES b/CHANGES index 929431c..76ff81d 100644 --- a/CHANGES +++ b/CHANGES
@@ -4,6 +4,13 @@ Changes between 0.9.6 and 0.9.7 [xx XXX 2000] + *) Fix for non blocking accept BIOs. Added new I/O special reason + BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs + with non blocking I/O was not possible because no retry code was + implemented. Also added new SSL code SSL_WANT_ACCEPT to cover + this case. + [Steve Henson] + *) Fix for bug in DirectoryString mask setting. Add support for X509_NAME_print_ex() in 'req' and X509_print_ex() function to allow certificate printing to more controllable, additional
diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c index e971a07..da2ff29 100644 --- a/crypto/bio/b_sock.c +++ b/crypto/bio/b_sock.c
@@ -661,6 +661,7 @@ ret=accept(sock,(struct sockaddr *)&from,(void *)&len); if (ret == INVALID_SOCKET) { + if(BIO_sock_should_retry(ret)) return -2; SYSerr(SYS_F_ACCEPT,get_last_socket_error()); BIOerr(BIO_F_BIO_ACCEPT,BIO_R_ACCEPT_ERROR); goto end;
diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h index 97003b5..c15f5e5 100644 --- a/crypto/bio/bio.h +++ b/crypto/bio/bio.h
@@ -179,7 +179,7 @@ #define BIO_retry_type(a) ((a)->flags & BIO_FLAGS_RWS) #define BIO_should_retry(a) ((a)->flags & BIO_FLAGS_SHOULD_RETRY) -/* The next two are used in conjunction with the +/* The next three are used in conjunction with the * BIO_should_io_special() condition. After this returns true, * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO * stack and return the 'reason' for the special and the offending BIO. @@ -188,6 +188,8 @@ #define BIO_RR_SSL_X509_LOOKUP 0x01 /* Returned from the connect BIO when a connect would have blocked */ #define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +#define BIO_RR_ACCEPT 0x03 /* These are passed by the BIO callback */ #define BIO_CB_FREE 0x01
diff --git a/crypto/bio/bss_acpt.c b/crypto/bio/bss_acpt.c index 4da5822..0c440fb 100644 --- a/crypto/bio/bss_acpt.c +++ b/crypto/bio/bss_acpt.c
@@ -236,8 +236,20 @@ c->state=ACPT_S_OK; goto again; } + BIO_clear_retry_flags(b); + b->retry_reason=0; i=BIO_accept(c->accept_sock,&(c->addr)); + + /* -2 return means we should retry */ + if(i == -2) + { + BIO_set_retry_special(b); + b->retry_reason=BIO_RR_ACCEPT; + return -1; + } + if (i < 0) return(i); + bio=BIO_new_socket(i,BIO_CLOSE); if (bio == NULL) goto err;
diff --git a/doc/crypto/BIO_s_accept.pod b/doc/crypto/BIO_s_accept.pod index c49da7f..b2b8e91 100644 --- a/doc/crypto/BIO_s_accept.pod +++ b/doc/crypto/BIO_s_accept.pod
@@ -92,7 +92,7 @@ called, after the accept BIO has been setup, it will attempt to create the accept socket and bind an address to it. Second and subsequent calls to BIO_do_accept() will await an incoming -connection. +connection, or request a retry in non blocking mode. =head1 NOTES @@ -130,6 +130,13 @@ connections. This can be resolved by using BIO_pop() (see above) and freeing up the accept BIO after the initial connection. +If the underlying accept socket is non blocking and BIO_do_accept() is +called to await an incoming connection it is possible for +BIO_should_io_special() with the reason BIO_RR_ACCEPT. If this happens +then it is an indication that an accept attempt would block: the application +should take appropriate action to wait until the underlying socket has +accepted a connection and retry the call. + =head1 RETURN VALUES TBA
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c index d85555a..9141ec0 100644 --- a/ssl/bio_ssl.c +++ b/ssl/bio_ssl.c
@@ -206,6 +206,10 @@ BIO_set_retry_special(b); retry_reason=BIO_RR_SSL_X509_LOOKUP; break; + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(b); + retry_reason=BIO_RR_ACCEPT; + break; case SSL_ERROR_WANT_CONNECT: BIO_set_retry_special(b); retry_reason=BIO_RR_CONNECT;
diff --git a/ssl/ssl.h b/ssl/ssl.h index 87e609e..2bc994a 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h
@@ -831,6 +831,7 @@ #define SSL_ERROR_SYSCALL 5 /* look at error stack/return value/errno */ #define SSL_ERROR_ZERO_RETURN 6 #define SSL_ERROR_WANT_CONNECT 7 +#define SSL_ERROR_WANT_ACCEPT 8 #define SSL_CTRL_NEED_TMP_RSA 1 #define SSL_CTRL_SET_TMP_RSA 2
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index fec98dd..ed2b820 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c
@@ -1543,6 +1543,8 @@ reason=BIO_get_retry_reason(bio); if (reason == BIO_RR_CONNECT) return(SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return(SSL_ERROR_WANT_ACCEPT); else return(SSL_ERROR_SYSCALL); /* unknown */ } @@ -1561,6 +1563,8 @@ reason=BIO_get_retry_reason(bio); if (reason == BIO_RR_CONNECT) return(SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return(SSL_ERROR_WANT_ACCEPT); else return(SSL_ERROR_SYSCALL); }