<html><head></head><body><div style="font-family: Verdana;font-size: 12.0px;"><div>
<div>Hello All,</div>

<div> </div>

<div>I experience the same problem as other people described in the past. Despite reading all the postings on the topic I am still not sure if there is a usable workaround to make spontaneous message exchange between server an client work:</div>

<div> </div>

<div>- both client and server exchange spontaneous application messages.<br/>
- both client and server use non-blocking sockets. SSL_read() and SSL_write() are serviced by one message pump thread.<br/>
- server initiates renegotiation with SSL_renegotiate()<br/>
- both client and server continue exchanging messages and renegotiation completes implicitly within the calls of SSL_read() and SSL_write()</div>

<div>--> sometimes (depending on timing) communication fails in client SSL_write() with 'unexpected record' because an application message is received instead of the expected renegotiation message.</div>

<div>So far, so good (bad)</div>

<div> </div>

<div>My question is if suppressing SSL_write() when SSL_renegotiate_pending() returns true would reliably avoid the problem:<br/>
 <br/>
Her the pseudo-code:</div>

<div>server<br/>
-------</div>

<div>while(1) {<br/>
    select()<br/>
    if needToRenegotiate() {<br/>
        SSL_renegotiate()<br/>
    }</div>

<div>    SSL_read() // always read<br/>
    if hasDataToSend() && !SSL_renegotiate_pending() {<br/>
        SSL_write()<br/>
    }  <br/>
    handleWantSomethingReturnCodes()<br/>
}</div>

<div><br/>
client<br/>
------</div>

<div>while(1) {<br/>
    select()<br/>
    SSL_read() // always read<br/>
    if hasDataToSend() && !SSL_renegotiate_pending() {<br/>
        SSL_write()<br/>
    }  <br/>
    handleWantSomethingReturnCodes()<br/>
}</div>

<div><br/>
Since I implemented this trick the error has never happened anymore, however, I wonder if the problem is really solved ot it just happens far less frequently in race conditions, e.g. when messages arrive between the check on SSL_renegotiate_pending() and SSL_write()</div>

<div>My interpretation of the logic in s3_pkt.c is that it's ok to receive application data between clientHello and serverHello in client or between helloRequest and clientHello in server. But this is just a guess.</div>

<div>Can somebody with good knowledge of the whole OpenSSL state-machine logic give an authoritative opinion?<br/>
 <br/>
    case SSL3_RT_APPLICATION_DATA:<br/>
        /*<br/>
         * At this point, we were expecting handshake data, but have<br/>
         * application data.  If the library was running inside ssl3_read()<br/>
         * (i.e. in_read_app_data is set) and it makes sense to read<br/>
         * application data at this point (session renegotiation not yet<br/>
         * started), we will indulge it.<br/>
         */<br/>
        if (s->s3->in_read_app_data &&<br/>
            (s->s3->total_renegotiations != 0) &&<br/>
            (((s->state & SSL_ST_CONNECT) &&<br/>
              (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&<br/>
              (s->state <= SSL3_ST_CR_SRVR_HELLO_A)<br/>
             ) || ((s->state & SSL_ST_ACCEPT) &&<br/>
                   (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&<br/>
                   (s->state >= SSL3_ST_SR_CLNT_HELLO_A)<br/>
             )<br/>
            )) {<br/>
            s->s3->in_read_app_data = 2;<br/>
            return (-1);<br/>
        } else {<br/>
            al = SSL_AD_UNEXPECTED_MESSAGE;<br/>
            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);<br/>
            goto f_err;<br/>
        }</div>

<div> </div>

<div>Many Thanks</div>

<div>Fabrizio</div>
</div></div></body></html>