Hello all,
I am trying to implement a pre-spawned daemon and I have some problems with the BIO_* socket.
The basic idea is this:
The father process sets up the bio, spawns 'n' processes. These processes compete on a SEMAPHORE and if they get the lock they will BIO_do_accept(), release the lock to the next child and take care of the communication with the client.
Here it is the father setting up the accept BIO socket:
----ooooo SNAP ooooo------------------
1 BIO *bio_socket = NULL;
2 BIO *buf_bio = NULL;
3
4 /* Set buffered bio */
5 buf_bio = BIO_new(BIO_f_buffer());
6 if (!buf_bio) {
7 ... Error ...;
8 }
9
10
11 /* Bind to socket */
12 if((bio_socket = BIO_new_accept( port )) == NULL ) {
13 ... Error ...;
14 }
15
16 BIO_set_accept_bios(bio_socket, buf_bio);
17 if (BIO_do_accept(bio_socket) <= 0)
18 {
19 ... Error...;
20
21 }
22
23 return bio_socket;----ooooo SNAP ooooo------------------
Now the server spawns 'n' child processes. The code of the children is the following:
----ooooo SNAP ooooo------------------
1 /* Get the Lock - actually using SEMAPHORES */
2 while ( 1 ) {
3 if( (got_lock = get_lock( ocspd_conf )) == 0 ) {
4 ... Error ...;
5 break;
6 }
7
8 if (BIO_do_accept( bio_socket ) <= 0) {
9 ... Error ...;
10 }
11
12 if( (curr_bio = BIO_pop( bio_socket )) == NULL ) {
13 ... Error ...;
14 }
15
16 /* Now release the lock so that other children can
17 compete on the lock and accept new connections */
18 if( (got_lock = lease_lock( ocspd_conf )) == 0 ) {
19 ...Error...;
20 }
21
22 /* Get input data from the bio */
23 if((req = get_request( curr_bio )) == NULL ) {
24 ...Error...;
25 }
26
27 /* Make and send the response */
28 if(( make_ocsp_response(&resp, req)) == 0 ) {
29 ... Error ...;
30 }
31 send_response( curr_bio, resp );
32
33 /* Free the BIO */
34 BIO_free_all( curr_bio );
35 }----ooooo SNAP ooooo------------------
Everything seems to work fine, but the problem is that the connection is not closed and I get hanging connection waiting while the client already disconnected - as reported by 'netstat -an':
tcp 0 0 0.0.0.0:2560 0.0.0.0:* LISTEN tcp 0 0 130.192.1.59:2560 130.192.1.59:35490 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35491 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35488 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35489 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35494 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35492 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35493 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35480 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35486 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35487 TIME_WAIT tcp 0 0 130.192.1.59:2560 130.192.1.59:35485 TIME_WAIT
The first is the server (bio_socket) while the others are pending connections (curr_bio). How to avoid this problem ???
I have also tried using 'BIO_free(curr_bio)' at line 34 (last snap), but then the BIO_do_accept() hangs the next cycle.
Someone has faced the same problem ? How to solve it ? Are there some flags I have to set when setting up the BIOs ? Do I have to flush/reset (how ???) the 'buf_bio' (line 16 of the first snap) before calling the BIO_free_all()?
Thanks in advance for the help. Have a nice day!
--
Best Regards,
Massimiliano Pala
--o------------------------------------------------------------------------
Massimiliano Pala [OpenCA Project Manager] [EMAIL PROTECTED]
Tel.: +39 (0)11 564 7081
http://security.polito.it Fax: +39 178 270 2077
Mobile: +39 (0)347 7222 365Politecnico di Torino (EuroPKI) Certification Authority Informations:
Authority Access Point http://ca.polito.it Authority's Certificate: http://ca.polito.it/ca_cert/en_index.html Certificate Revocation List: http://ca.polito.it/crl02/crl.crl --o------------------------------------------------------------------------
smime.p7s
Description: S/MIME Cryptographic Signature
