Ignore:
Timestamp:
Mar 6, 2018 8:44:18 AM (7 years ago)
Author:
nanang
Message:

Fixed #2099: Fixed SSL socket (OpenSSL backend), when sending buffer is full, any further send operation should be rejected immediately without writing to OpenSSL SSL BIO.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c

    r5726 r5751  
    264264    pj_bool_t             flushing_write_pend; /* flag of flushing is ongoing*/ 
    265265    send_buf_t            send_buf; 
     266    write_data_t          send_buf_pending; /* send buffer is full but some 
     267                                             * data is queuing in wbio.     */ 
    266268    write_data_t          send_pending; /* list of pending write to network */ 
    267269    pj_lock_t            *write_mutex;  /* protect write BIO and send_buf   */ 
     
    18901892    wdata = alloc_send_data(ssock, needed_len); 
    18911893    if (wdata == NULL) { 
     1894        /* Oops, write BIO is ready but the send buffer is full, let's just 
     1895         * queue it for sending and return PJ_EPENDING. 
     1896         */ 
     1897        ssock->send_buf_pending.data_len = needed_len; 
     1898        ssock->send_buf_pending.app_key = send_key; 
     1899        ssock->send_buf_pending.flags = flags; 
     1900        ssock->send_buf_pending.plain_data_len = orig_len; 
    18921901        pj_lock_release(ssock->write_mutex); 
    1893         return PJ_ENOMEM; 
     1902        return PJ_EPENDING; 
    18941903    } 
    18951904 
     
    21932202    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*) 
    21942203                           pj_activesock_get_user_data(asock); 
    2195  
    2196     PJ_UNUSED_ARG(send_key); 
    2197     PJ_UNUSED_ARG(sent); 
     2204    write_data_t *wdata = (write_data_t*)send_key->user_data; 
     2205    pj_ioqueue_op_key_t *app_key = wdata->app_key; 
     2206    pj_ssize_t sent_len; 
     2207 
     2208    sent_len = (sent > 0)? wdata->plain_data_len : sent; 
     2209     
     2210    /* Update write buffer state */ 
     2211    pj_lock_acquire(ssock->write_mutex); 
     2212    free_send_data(ssock, wdata); 
     2213    pj_lock_release(ssock->write_mutex); 
     2214    wdata = NULL; 
    21982215 
    21992216    if (ssock->ssl_state == SSL_STATE_HANDSHAKING) { 
     
    22082225    } else if (send_key != &ssock->handshake_op_key) { 
    22092226        /* Some data has been sent, notify application */ 
    2210         write_data_t *wdata = (write_data_t*)send_key->user_data; 
    22112227        if (ssock->param.cb.on_data_sent) { 
    22122228            pj_bool_t ret; 
    2213             pj_ssize_t sent_len; 
    2214  
    2215             sent_len = (sent > 0)? wdata->plain_data_len : sent; 
    2216             ret = (*ssock->param.cb.on_data_sent)(ssock, wdata->app_key,  
     2229            ret = (*ssock->param.cb.on_data_sent)(ssock, app_key,  
    22172230                                                  sent_len); 
    22182231            if (!ret) { 
     
    22212234            } 
    22222235        } 
    2223  
    2224         /* Update write buffer state */ 
    2225         pj_lock_acquire(ssock->write_mutex); 
    2226         free_send_data(ssock, wdata); 
    2227         pj_lock_release(ssock->write_mutex); 
    2228  
    22292236    } else { 
    22302237        /* SSL re-negotiation is on-progress, just do nothing */ 
     2238    } 
     2239 
     2240    /* Send buffer has been updated, let's try to send any pending data */ 
     2241    if (ssock->send_buf_pending.data_len) { 
     2242        pj_status_t status; 
     2243        status = flush_write_bio(ssock, ssock->send_buf_pending.app_key, 
     2244                                 ssock->send_buf_pending.plain_data_len, 
     2245                                 ssock->send_buf_pending.flags); 
     2246        if (status == PJ_SUCCESS || status == PJ_EPENDING) { 
     2247            ssock->send_buf_pending.data_len = 0; 
     2248        } 
    22312249    } 
    22322250 
     
    29983016     */ 
    29993017    pj_lock_acquire(ssock->write_mutex); 
     3018    /* Don't write to SSL if send buffer is full and some data is in 
     3019     * write BIO already, just return PJ_ENOMEM. 
     3020     */ 
     3021    if (ssock->send_buf_pending.data_len) { 
     3022        pj_lock_release(ssock->write_mutex); 
     3023        return PJ_ENOMEM; 
     3024    } 
    30003025    nwritten = SSL_write(ssock->ossl_ssl, data, (int)size); 
    30013026    pj_lock_release(ssock->write_mutex); 
Note: See TracChangeset for help on using the changeset viewer.