Ignore:
Timestamp:
Mar 4, 2019 9:47:25 AM (4 months ago)
Author:
ming
Message:

Fixed #2180: Refactoring SSL socket backend implementations

File:
1 edited

Legend:

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

    r5929 r5938  
    4545    (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_GNUTLS) 
    4646 
     47#define SSL_SOCK_IMP_USE_CIRC_BUF 
     48 
     49#include "ssl_sock_imp_common.h" 
     50#include "ssl_sock_imp_common.c" 
     51 
    4752#define THIS_FILE               "ssl_sock_gtls.c" 
    48  
    49 /* Workaround for ticket #985 */ 
    50 #define DELAYED_CLOSE_TIMEOUT   200 
    5153 
    5254/* Maximum ciphers */ 
     
    7072 
    7173 
    72 /* TLS state enumeration. */ 
    73 enum tls_connection_state { 
    74     TLS_STATE_NULL, 
    75     TLS_STATE_HANDSHAKING, 
    76     TLS_STATE_ESTABLISHED 
    77 }; 
    78  
    79 /* Internal timer types. */ 
    80 enum timer_id { 
    81     TIMER_NONE, 
    82     TIMER_HANDSHAKE_TIMEOUT, 
    83     TIMER_CLOSE 
    84 }; 
    85  
    86 /* Structure of SSL socket read buffer. */ 
    87 typedef struct read_data_t { 
    88     void *data; 
    89     pj_size_t len; 
    90 } read_data_t; 
    91  
    92 /* 
    93  * Get the offset of pointer to read-buffer of SSL socket from read-buffer 
    94  * of active socket. Note that both SSL socket and active socket employ 
    95  * different but correlated read-buffers (as much as async_cnt for each), 
    96  * and to make it easier/faster to find corresponding SSL socket's read-buffer 
    97  * from known active socket's read-buffer, the pointer of corresponding 
    98  * SSL socket's read-buffer is stored right after the end of active socket's 
    99  * read-buffer. 
    100  */ 
    101 #define OFFSET_OF_READ_DATA_PTR(ssock, asock_rbuf) \ 
    102                                         (read_data_t**) \ 
    103                                         ((pj_int8_t *)(asock_rbuf) + \ 
    104                                         ssock->param.read_buffer_size) 
    105  
    106 /* Structure of SSL socket write data. */ 
    107 typedef struct write_data_t { 
    108     PJ_DECL_LIST_MEMBER(struct write_data_t); 
    109     pj_ioqueue_op_key_t  key; 
    110     pj_size_t            record_len; 
    111     pj_ioqueue_op_key_t *app_key; 
    112     pj_size_t            plain_data_len; 
    113     pj_size_t            data_len; 
    114     unsigned             flags; 
    115     union { 
    116         char             content[1]; 
    117         const char      *ptr; 
    118     } data; 
    119 } write_data_t; 
    120  
    121  
    122 /* Structure of SSL socket write buffer (circular buffer). */ 
    123 typedef struct send_buf_t { 
    124     char                *buf; 
    125     pj_size_t            max_len; 
    126     char                *start; 
    127     pj_size_t            len; 
    128 } send_buf_t; 
    129  
    130  
    131 /* Circular buffer object */ 
    132 typedef struct circ_buf_t { 
    133     pj_size_t      cap;    /* maximum number of elements (must be power of 2) */ 
    134     pj_size_t      readp;  /* index of oldest element */ 
    135     pj_size_t      writep; /* index at which to write new element  */ 
    136     pj_size_t      size;   /* number of elements */ 
    137     pj_uint8_t    *buf;    /* data buffer */ 
    138     pj_pool_t     *pool;   /* where new allocations will take place */ 
    139 } circ_buf_t; 
    140  
    141  
    14274/* Secure socket structure definition. */ 
    143 struct pj_ssl_sock_t { 
    144     pj_pool_t            *pool; 
    145     pj_ssl_sock_t        *parent; 
    146     pj_ssl_sock_param     param; 
    147     pj_ssl_sock_param     newsock_param; 
    148     pj_ssl_cert_t        *cert; 
    149  
    150     pj_ssl_cert_info      local_cert_info; 
    151     pj_ssl_cert_info      remote_cert_info; 
    152  
    153     pj_bool_t             is_server; 
    154     enum tls_connection_state connection_state; 
    155     pj_ioqueue_op_key_t   handshake_op_key; 
    156     pj_timer_entry        timer; 
    157     pj_status_t           verify_status; 
    158  
    159     int                   last_err; 
    160  
    161     pj_sock_t             sock; 
    162     pj_activesock_t      *asock; 
    163  
    164     pj_sockaddr           local_addr; 
    165     pj_sockaddr           rem_addr; 
    166     int                   addr_len; 
    167  
    168     pj_bool_t             read_started; 
    169     pj_size_t             read_size; 
    170     pj_uint32_t           read_flags; 
    171     void                **asock_rbuf; 
    172     read_data_t          *ssock_rbuf; 
    173  
    174     write_data_t          write_pending;       /* list of pending writes */ 
    175     write_data_t          write_pending_empty; /* cache for write_pending */ 
    176     pj_bool_t             flushing_write_pend; /* flag of flushing is ongoing */ 
    177     send_buf_t            send_buf; 
    178     write_data_t          send_pending; /* list of pending write to network */ 
     75typedef struct gnutls_sock_t { 
     76    pj_ssl_sock_t         base; 
    17977 
    18078    gnutls_session_t      session; 
    18179    gnutls_certificate_credentials_t xcred; 
    18280 
    183     circ_buf_t            circ_buf_input; 
    184     pj_lock_t            *circ_buf_input_mutex; 
    185  
    186     circ_buf_t            circ_buf_output; 
    187     pj_lock_t            *circ_buf_output_mutex; 
    188  
    18981    int                   tls_init_count; /* library initialization counter */ 
    190 }; 
    191  
    192 /* 
    193  * Certificate/credential structure definition. 
    194  */ 
    195 struct pj_ssl_cert_t 
    196 { 
    197     pj_str_t CA_file; 
    198     pj_str_t CA_path; 
    199     pj_str_t cert_file; 
    200     pj_str_t privkey_file; 
    201     pj_str_t privkey_pass; 
    202  
    203     /* Certificate buffer. */ 
    204     pj_ssl_cert_buffer CA_buf; 
    205     pj_ssl_cert_buffer cert_buf; 
    206     pj_ssl_cert_buffer privkey_buf; 
    207 }; 
    208  
    209  
    210 /* GnuTLS available ciphers */ 
    211 static unsigned tls_available_ciphers; 
    212  
    213 /* Array of id/names for available ciphers */ 
    214 static struct tls_ciphers_t { 
    215     pj_ssl_cipher id; 
    216     const char *name; 
    217 } tls_ciphers[MAX_CIPHERS]; 
     82} gnutls_sock_t; 
    21883 
    21984/* Last error reported somehow */ 
    22085static int tls_last_error; 
    221  
    222  
    223 /* 
    224  ******************************************************************* 
    225  * Circular buffer functions. 
    226  ******************************************************************* 
    227  */ 
    228  
    229 static pj_status_t circ_init(pj_pool_factory *factory, 
    230                              circ_buf_t *cb, pj_size_t cap) 
    231 { 
    232     cb->cap    = cap; 
    233     cb->readp  = 0; 
    234     cb->writep = 0; 
    235     cb->size   = 0; 
    236  
    237     /* Initial pool holding the buffer elements */ 
    238     cb->pool = pj_pool_create(factory, "tls-circ%p", cap, cap, NULL); 
    239     if (!cb->pool) 
    240         return PJ_ENOMEM; 
    241  
    242     /* Allocate circular buffer */ 
    243     cb->buf = pj_pool_alloc(cb->pool, cap); 
    244     if (!cb->buf) { 
    245         pj_pool_release(cb->pool); 
    246         return PJ_ENOMEM; 
    247     } 
    248  
    249     return PJ_SUCCESS; 
    250 } 
    251  
    252 static void circ_deinit(circ_buf_t *cb) 
    253 { 
    254     if (cb->pool) { 
    255         pj_pool_release(cb->pool); 
    256         cb->pool = NULL; 
    257     } 
    258 } 
    259  
    260 static pj_bool_t circ_empty(const circ_buf_t *cb) 
    261 { 
    262     return cb->size == 0; 
    263 } 
    264  
    265 static pj_size_t circ_size(const circ_buf_t *cb) 
    266 { 
    267     return cb->size; 
    268 } 
    269  
    270 static pj_size_t circ_avail(const circ_buf_t *cb) 
    271 { 
    272     return cb->cap - cb->size; 
    273 } 
    274  
    275 static void circ_read(circ_buf_t *cb, pj_uint8_t *dst, pj_size_t len) 
    276 { 
    277     pj_size_t size_after = cb->cap - cb->readp; 
    278     pj_size_t tbc = PJ_MIN(size_after, len); 
    279     pj_size_t rem = len - tbc; 
    280  
    281     pj_memcpy(dst, cb->buf + cb->readp, tbc); 
    282     pj_memcpy(dst + tbc, cb->buf, rem); 
    283  
    284     cb->readp += len; 
    285     cb->readp &= (cb->cap - 1); 
    286  
    287     cb->size -= len; 
    288 } 
    289  
    290 static pj_status_t circ_write(circ_buf_t *cb, 
    291                               const pj_uint8_t *src, pj_size_t len) 
    292 { 
    293     /* Overflow condition: resize */ 
    294     if (len > circ_avail(cb)) { 
    295         /* Minimum required capacity */ 
    296         pj_size_t min_cap = len + cb->size; 
    297  
    298         /* Next 32-bit power of two */ 
    299         min_cap--; 
    300         min_cap |= min_cap >> 1; 
    301         min_cap |= min_cap >> 2; 
    302         min_cap |= min_cap >> 4; 
    303         min_cap |= min_cap >> 8; 
    304         min_cap |= min_cap >> 16; 
    305         min_cap++; 
    306  
    307         /* Create a new pool to hold a bigger buffer, using the same factory */ 
    308         pj_pool_t *pool = pj_pool_create(cb->pool->factory, "tls-circ%p", 
    309                                          min_cap, min_cap, NULL); 
    310         if (!pool) 
    311             return PJ_ENOMEM; 
    312  
    313         /* Allocate our new buffer */ 
    314         pj_uint8_t *buf = pj_pool_alloc(pool, min_cap); 
    315         if (!buf) { 
    316             pj_pool_release(pool); 
    317             return PJ_ENOMEM; 
    318         } 
    319  
    320         /* Save old size, which we shall restore after the next read */ 
    321         pj_size_t old_size = cb->size; 
    322  
    323         /* Copy old data into beginning of new buffer */ 
    324         circ_read(cb, buf, cb->size); 
    325  
    326         /* Restore old size now */ 
    327         cb->size = old_size; 
    328  
    329         /* Release the previous pool */ 
    330         pj_pool_release(cb->pool); 
    331  
    332         /* Update circular buffer members */ 
    333         cb->pool = pool; 
    334         cb->buf = buf; 
    335         cb->readp = 0; 
    336         cb->writep = cb->size; 
    337         cb->cap = min_cap; 
    338     } 
    339  
    340     pj_size_t size_after = cb->cap - cb->writep; 
    341     pj_size_t tbc = PJ_MIN(size_after, len); 
    342     pj_size_t rem = len - tbc; 
    343  
    344     pj_memcpy(cb->buf + cb->writep, src, tbc); 
    345     pj_memcpy(cb->buf, src + tbc, rem); 
    346  
    347     cb->writep += len; 
    348     cb->writep &= (cb->cap - 1); 
    349  
    350     cb->size += len; 
    351  
    352     return PJ_SUCCESS; 
    353 } 
    35486 
    35587 
     
    491223 
    492224    /* Init available ciphers */ 
    493     if (!tls_available_ciphers) { 
     225    if (!ssl_cipher_num) { 
    494226        unsigned int i; 
    495227 
    496         for (i = 0; i<PJ_ARRAY_SIZE(tls_ciphers); i++) { 
     228        for (i = 0; i<PJ_ARRAY_SIZE(ssl_ciphers); i++) { 
    497229            unsigned char id[2]; 
    498230            const char *suite; 
     
    500232            suite = gnutls_cipher_suite_info(i, (unsigned char *)id, 
    501233                                             NULL, NULL, NULL, NULL); 
    502             tls_ciphers[i].id = 0; 
     234            ssl_ciphers[i].id = 0; 
    503235            /* usually the array size is bigger than the number of available 
    504236             * ciphers anyway, so by checking here we can exit the loop as soon 
    505237             * as either all ciphers have been added or the array is full */ 
    506238            if (suite) { 
    507                 tls_ciphers[i].id = (pj_ssl_cipher) 
     239                ssl_ciphers[i].id = (pj_ssl_cipher) 
    508240                    (pj_uint32_t) ((id[0] << 8) | id[1]); 
    509                 tls_ciphers[i].name = suite; 
     241                ssl_ciphers[i].name = suite; 
    510242            } else 
    511243                break; 
    512244        } 
    513245 
    514         tls_available_ciphers = i; 
     246        ssl_cipher_num = i; 
    515247    } 
    516248 
     
    623355{ 
    624356    pj_ssl_sock_t *ssock = (pj_ssl_sock_t *)ptr; 
     357    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    625358 
    626359    pj_lock_acquire(ssock->circ_buf_output_mutex); 
     
    628361        pj_lock_release(ssock->circ_buf_output_mutex); 
    629362 
    630         gnutls_transport_set_errno(ssock->session, ENOMEM); 
     363        gnutls_transport_set_errno(gssock->session, ENOMEM); 
    631364        return -1; 
    632365    } 
     
    644377{ 
    645378    pj_ssl_sock_t *ssock = (pj_ssl_sock_t *)ptr; 
     379    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    646380 
    647381    pj_lock_acquire(ssock->circ_buf_input_mutex); 
     
    651385 
    652386        /* Data buffers not yet filled */ 
    653         gnutls_transport_set_errno(ssock->session, EAGAIN); 
     387        gnutls_transport_set_errno(gssock->session, EAGAIN); 
    654388        return -1; 
    655389    } 
     
    684418static pj_status_t tls_priorities_set(pj_ssl_sock_t *ssock) 
    685419{ 
     420    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    686421    char buf[1024]; 
    687422    char priority_buf[256]; 
     
    783518 
    784519    /* Set our priority string */ 
    785     ret = gnutls_priority_set_direct(ssock->session, 
     520    ret = gnutls_priority_set_direct(gssock->session, 
    786521                                        cipher_list.ptr, &err); 
    787522    if (ret < 0) { 
     
    797532static pj_status_t tls_trust_set(pj_ssl_sock_t *ssock) 
    798533{ 
     534    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    799535    int ntrusts = 0; 
    800536    int err; 
    801537 
    802     err = gnutls_certificate_set_x509_system_trust(ssock->xcred); 
     538    err = gnutls_certificate_set_x509_system_trust(gssock->xcred); 
    803539    if (err > 0) 
    804540        ntrusts += err; 
    805     err = gnutls_certificate_set_x509_trust_file(ssock->xcred, 
     541    err = gnutls_certificate_set_x509_trust_file(gssock->xcred, 
    806542                                                 TRUST_STORE_FILE1, 
    807543                                                 GNUTLS_X509_FMT_PEM); 
     
    809545        ntrusts += err; 
    810546 
    811     err = gnutls_certificate_set_x509_trust_file(ssock->xcred, 
     547    err = gnutls_certificate_set_x509_trust_file(gssock->xcred, 
    812548                                                 TRUST_STORE_FILE2, 
    813549                                                 GNUTLS_X509_FMT_PEM); 
     
    875611#endif 
    876612 
     613static pj_ssl_sock_t *ssl_alloc(pj_pool_t *pool) 
     614{ 
     615    return (pj_ssl_sock_t *)PJ_POOL_ZALLOC_T(pool, gnutls_sock_t); 
     616} 
     617 
    877618/* Create and initialize new GnuTLS context and instance */ 
    878 static pj_status_t tls_open(pj_ssl_sock_t *ssock) 
    879 { 
     619static pj_status_t ssl_create(pj_ssl_sock_t *ssock) 
     620{ 
     621    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    880622    pj_ssl_cert_t *cert; 
    881623    pj_status_t status; 
     
    888630    /* Even if reopening is harmless, having one instance only simplifies 
    889631     * deallocating it later on */ 
    890     if (!ssock->tls_init_count) { 
    891         ssock->tls_init_count++; 
     632    if (!gssock->tls_init_count) { 
     633        gssock->tls_init_count++; 
    892634        ret = tls_init(); 
    893635        if (ret < 0) 
     
    897639 
    898640    /* Start this socket session */ 
    899     ret = gnutls_init(&ssock->session, ssock->is_server ? GNUTLS_SERVER 
     641    ret = gnutls_init(&gssock->session, ssock->is_server ? GNUTLS_SERVER 
    900642                                                        : GNUTLS_CLIENT); 
    901643    if (ret < 0) 
     
    904646    /* Set the ssock object to be retrieved by transport (send/recv) and by 
    905647     * user data from this session */ 
    906     gnutls_transport_set_ptr(ssock->session, 
     648    gnutls_transport_set_ptr(gssock->session, 
    907649                             (gnutls_transport_ptr_t) (uintptr_t) ssock); 
    908     gnutls_session_set_ptr(ssock->session, 
     650    gnutls_session_set_ptr(gssock->session, 
    909651                           (gnutls_transport_ptr_t) (uintptr_t) ssock); 
    910652 
     
    921663    /* Set the callback that allows GnuTLS to PUSH and PULL data 
    922664     * TO and FROM the transport layer */ 
    923     gnutls_transport_set_push_function(ssock->session, tls_data_push); 
    924     gnutls_transport_set_pull_function(ssock->session, tls_data_pull); 
     665    gnutls_transport_set_push_function(gssock->session, tls_data_push); 
     666    gnutls_transport_set_pull_function(gssock->session, tls_data_pull); 
    925667 
    926668    /* Determine which cipher suite to support */ 
     
    930672 
    931673    /* Allocate credentials for handshaking and transmission */ 
    932     ret = gnutls_certificate_allocate_credentials(&ssock->xcred); 
     674    ret = gnutls_certificate_allocate_credentials(&gssock->xcred); 
    933675    if (ret < 0) 
    934676        goto out; 
    935     gnutls_certificate_set_verify_function(ssock->xcred, tls_cert_verify_cb); 
     677    gnutls_certificate_set_verify_function(gssock->xcred, tls_cert_verify_cb); 
    936678 
    937679    /* Load system trust file(s) */ 
     
    944686        /* Load CA if one is specified. */ 
    945687        if (cert->CA_file.slen) { 
    946             ret = gnutls_certificate_set_x509_trust_file(ssock->xcred, 
     688            ret = gnutls_certificate_set_x509_trust_file(gssock->xcred, 
    947689                                                         cert->CA_file.ptr, 
    948690                                                         GNUTLS_X509_FMT_PEM); 
    949691            if (ret < 0) 
    950692                ret = gnutls_certificate_set_x509_trust_file( 
    951                                 ssock->xcred, 
     693                                gssock->xcred, 
    952694                                cert->CA_file.ptr, 
    953695                                GNUTLS_X509_FMT_DER); 
     
    956698        } 
    957699        if (cert->CA_path.slen) { 
    958             ret = gnutls_certificate_set_x509_trust_dir(ssock->xcred, 
     700            ret = gnutls_certificate_set_x509_trust_dir(gssock->xcred, 
    959701                                                         cert->CA_path.ptr, 
    960702                                                         GNUTLS_X509_FMT_PEM); 
    961703            if (ret < 0) 
    962704                ret = gnutls_certificate_set_x509_trust_dir( 
    963                                 ssock->xcred, 
     705                                gssock->xcred, 
    964706                                cert->CA_path.ptr, 
    965707                                GNUTLS_X509_FMT_DER); 
     
    974716                                    ? cert->privkey_pass.ptr 
    975717                                    : NULL; 
    976             ret = gnutls_certificate_set_x509_key_file2(ssock->xcred, 
     718            ret = gnutls_certificate_set_x509_key_file2(gssock->xcred, 
    977719                                                        cert->cert_file.ptr, 
    978720                                                        prikey_file, 
     
    981723                                                        0); 
    982724            if (ret != GNUTLS_E_SUCCESS) 
    983                 ret = gnutls_certificate_set_x509_key_file2(ssock->xcred, 
     725                ret = gnutls_certificate_set_x509_key_file2(gssock->xcred, 
    984726                                                            cert->cert_file.ptr, 
    985727                                                            prikey_file, 
     
    995737            ca.data = (unsigned char*)cert->CA_buf.ptr; 
    996738            ca.size = cert->CA_buf.slen; 
    997             ret = gnutls_certificate_set_x509_trust_mem(ssock->xcred, 
     739            ret = gnutls_certificate_set_x509_trust_mem(gssock->xcred, 
    998740                                                        &ca, 
    999741                                                        GNUTLS_X509_FMT_PEM); 
    1000742            if (ret < 0) 
    1001743                ret = gnutls_certificate_set_x509_trust_mem( 
    1002                                 ssock->xcred, &ca, GNUTLS_X509_FMT_DER); 
     744                                gssock->xcred, &ca, GNUTLS_X509_FMT_DER); 
    1003745            if (ret < 0) 
    1004746                goto out; 
     
    1017759                                    ? cert->privkey_pass.ptr 
    1018760                                    : NULL; 
    1019             ret = gnutls_certificate_set_x509_key_mem2(ssock->xcred, 
     761            ret = gnutls_certificate_set_x509_key_mem2(gssock->xcred, 
    1020762                                                       &cert_buf, 
    1021763                                                       &privkey_buf, 
     
    1026768            /* 
    1027769            if (ret != GNUTLS_E_SUCCESS) 
    1028                 ret = gnutls_certificate_set_x509_key_mem2(ssock->xcred, 
     770                ret = gnutls_certificate_set_x509_key_mem2(gssock->xcred, 
    1029771                                                           &cert_buf, 
    1030772                                                           &privkey_buf, 
     
    1040782    /* Require client certificate if asked */ 
    1041783    if (ssock->is_server && ssock->param.require_client_cert) 
    1042         gnutls_certificate_server_set_request(ssock->session, 
     784        gnutls_certificate_server_set_request(gssock->session, 
    1043785                                              GNUTLS_CERT_REQUIRE); 
    1044786 
    1045787    /* Finally set credentials for this session */ 
    1046     ret = gnutls_credentials_set(ssock->session, 
    1047                                  GNUTLS_CRD_CERTIFICATE, ssock->xcred); 
     788    ret = gnutls_credentials_set(gssock->session, 
     789                                 GNUTLS_CRD_CERTIFICATE, gssock->xcred); 
    1048790    if (ret < 0) 
    1049791        goto out; 
     
    1056798 
    1057799/* Destroy GnuTLS credentials and session. */ 
    1058 static void tls_close(pj_ssl_sock_t *ssock) 
    1059 { 
    1060     if (ssock->session) { 
    1061         gnutls_bye(ssock->session, GNUTLS_SHUT_RDWR); 
    1062         gnutls_deinit(ssock->session); 
    1063         ssock->session = NULL; 
    1064     } 
    1065  
    1066     if (ssock->xcred) { 
    1067         gnutls_certificate_free_credentials(ssock->xcred); 
    1068         ssock->xcred = NULL; 
     800static void ssl_destroy(pj_ssl_sock_t *ssock) 
     801{ 
     802    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
     803 
     804    if (gssock->session) { 
     805        gnutls_bye(gssock->session, GNUTLS_SHUT_RDWR); 
     806        gnutls_deinit(gssock->session); 
     807        gssock->session = NULL; 
     808    } 
     809 
     810    if (gssock->xcred) { 
     811        gnutls_certificate_free_credentials(gssock->xcred); 
     812        gssock->xcred = NULL; 
    1069813    } 
    1070814 
    1071815    /* Free GnuTLS library */ 
    1072     if (ssock->tls_init_count) { 
    1073         ssock->tls_init_count--; 
     816    if (gssock->tls_init_count) { 
     817        gssock->tls_init_count--; 
    1074818        tls_deinit(); 
    1075819    } 
     
    1082826 
    1083827/* Reset socket state. */ 
    1084 static void tls_sock_reset(pj_ssl_sock_t *ssock) 
    1085 { 
    1086     ssock->connection_state = TLS_STATE_NULL; 
    1087  
    1088     tls_close(ssock); 
    1089  
    1090     if (ssock->asock) { 
    1091         pj_activesock_close(ssock->asock); 
    1092         ssock->asock = NULL; 
    1093         ssock->sock = PJ_INVALID_SOCKET; 
    1094     } 
    1095     if (ssock->sock != PJ_INVALID_SOCKET) { 
    1096         pj_sock_close(ssock->sock); 
    1097         ssock->sock = PJ_INVALID_SOCKET; 
    1098     } 
     828static void ssl_reset_sock_state(pj_ssl_sock_t *ssock) 
     829{ 
     830    pj_lock_acquire(ssock->circ_buf_output_mutex); 
     831    ssock->ssl_state = SSL_STATE_NULL; 
     832    pj_lock_release(ssock->circ_buf_output_mutex); 
     833 
     834    ssl_close_sockets(ssock); 
    1099835 
    1100836    ssock->last_err = tls_last_error = GNUTLS_E_SUCCESS; 
     837} 
     838 
     839 
     840static void ssl_ciphers_populate(void) 
     841{ 
     842     if (!ssl_cipher_num) { 
     843         tls_init(); 
     844         tls_deinit(); 
     845     } 
     846} 
     847 
     848 
     849static pj_ssl_cipher ssl_get_cipher(pj_ssl_sock_t *ssock) 
     850{ 
     851    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
     852    int i; 
     853    gnutls_cipher_algorithm_t lookup; 
     854    gnutls_cipher_algorithm_t cipher; 
     855 
     856    /* Current cipher */ 
     857    cipher = gnutls_cipher_get(gssock->session); 
     858    for (i = 0; ; i++) { 
     859        unsigned char id[2]; 
     860        const char *suite; 
     861         
     862        suite = gnutls_cipher_suite_info(i,(unsigned char *)id, NULL, 
     863                                         &lookup, NULL, NULL); 
     864        if (suite) { 
     865            if (lookup == cipher) { 
     866                return (pj_uint32_t) ((id[0] << 8) | id[1]); 
     867            } 
     868        } else { 
     869            break; 
     870        } 
     871    } 
     872 
     873    return PJ_TLS_UNKNOWN_CIPHER; 
    1101874} 
    1102875 
     
    12521025/* Update local & remote certificates info. This function should be 
    12531026 * called after handshake or renegotiation successfully completed. */ 
    1254 static void tls_cert_update(pj_ssl_sock_t *ssock) 
    1255 { 
     1027static void ssl_update_certs_info(pj_ssl_sock_t *ssock) 
     1028{ 
     1029    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    12561030    gnutls_x509_crt_t cert = NULL; 
    12571031    const gnutls_datum_t *us; 
     
    12601034    int ret = GNUTLS_CERT_INVALID; 
    12611035 
    1262     pj_assert(ssock->connection_state == TLS_STATE_ESTABLISHED); 
     1036    pj_assert(ssock->ssl_state == SSL_STATE_ESTABLISHED); 
    12631037 
    12641038    /* Get active local certificate */ 
    1265     us = gnutls_certificate_get_ours(ssock->session); 
     1039    us = gnutls_certificate_get_ours(gssock->session); 
    12661040    if (!us) 
    12671041        goto us_out; 
     
    12891063 
    12901064    /* Get active remote certificate */ 
    1291     certs = gnutls_certificate_get_peers(ssock->session, &certslen); 
     1065    certs = gnutls_certificate_get_peers(gssock->session, &certslen); 
    12921066    if (certs == NULL || certslen == 0) 
    12931067        goto peer_out; 
     
    13151089} 
    13161090 
    1317  
    1318 /* When handshake completed: 
    1319  * - notify application 
    1320  * - if handshake failed, reset SSL state 
    1321  * - return PJ_FALSE when SSL socket instance is destroyed by application. */ 
    1322 static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock, 
    1323                                        pj_status_t status) 
    1324 { 
    1325     pj_bool_t ret = PJ_TRUE; 
    1326  
    1327     /* Cancel handshake timer */ 
    1328     if (ssock->timer.id == TIMER_HANDSHAKE_TIMEOUT) { 
    1329         pj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer); 
    1330         ssock->timer.id = TIMER_NONE; 
    1331     } 
    1332  
    1333     /* Update certificates info on successful handshake */ 
    1334     if (status == PJ_SUCCESS) 
    1335         tls_cert_update(ssock); 
    1336  
    1337     /* Accepting */ 
    1338     if (ssock->is_server) { 
    1339         if (status != PJ_SUCCESS) { 
    1340             /* Handshake failed in accepting, destroy our self silently. */ 
    1341  
    1342             char errmsg[PJ_ERR_MSG_SIZE]; 
    1343             char buf[PJ_INET6_ADDRSTRLEN + 10]; 
    1344  
    1345             pj_strerror(status, errmsg, sizeof(errmsg)); 
     1091static void ssl_set_state(pj_ssl_sock_t *ssock, pj_bool_t is_server) 
     1092{ 
     1093    PJ_UNUSED_ARG(ssock); 
     1094    PJ_UNUSED_ARG(is_server); 
     1095} 
     1096 
     1097static void ssl_set_peer_name(pj_ssl_sock_t *ssock) 
     1098{ 
     1099    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
     1100 
     1101    /* Set server name to connect */ 
     1102    if (ssock->param.server_name.slen) { 
     1103        int ret; 
     1104        /* Server name is null terminated already */ 
     1105        ret = gnutls_server_name_set(gssock->session, GNUTLS_NAME_DNS, 
     1106                                     ssock->param.server_name.ptr, 
     1107                                     ssock->param.server_name.slen); 
     1108        if (ret < 0) { 
    13461109            PJ_LOG(3, (ssock->pool->obj_name, 
    1347                        "Handshake failed in accepting %s: %s", 
    1348                        pj_sockaddr_print(&ssock->rem_addr, buf,sizeof(buf),3), 
    1349                        errmsg)); 
    1350  
    1351             /* Workaround for ticket #985 */ 
    1352 #if (defined(PJ_WIN32)&& PJ_WIN32 != 0) || (defined(PJ_WIN64)&& PJ_WIN64 != 0) 
    1353             if (ssock->param.timer_heap) { 
    1354                 pj_time_val interval = {0, DELAYED_CLOSE_TIMEOUT}; 
    1355  
    1356                 tls_sock_reset(ssock); 
    1357  
    1358                 ssock->timer.id = TIMER_CLOSE; 
    1359                 pj_time_val_normalize(&interval); 
    1360                 if (pj_timer_heap_schedule(ssock->param.timer_heap, 
    1361                                            &ssock->timer, &interval) != 0) 
    1362                 { 
    1363                     ssock->timer.id = TIMER_NONE; 
    1364                     pj_ssl_sock_close(ssock); 
    1365                 } 
    1366             } else 
    1367 #endif /* PJ_WIN32 */ 
    1368             { 
    1369                 pj_ssl_sock_close(ssock); 
    1370             } 
    1371  
    1372             return PJ_FALSE; 
    1373         } 
    1374         /* Notify application the newly accepted SSL socket */ 
    1375         if (ssock->param.cb.on_accept_complete) 
    1376             ret = (*ssock->param.cb.on_accept_complete) 
    1377                       (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr, 
    1378                        pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr)); 
    1379  
    1380     } else { /* Connecting */ 
    1381         /* On failure, reset SSL socket state first, as app may try to 
    1382          * reconnect in the callback. */ 
    1383         if (status != PJ_SUCCESS) { 
    1384             /* Server disconnected us, possibly due to negotiation failure */ 
    1385             tls_sock_reset(ssock); 
    1386         } 
    1387         if (ssock->param.cb.on_connect_complete) { 
    1388  
    1389             ret = (*ssock->param.cb.on_connect_complete)(ssock, status); 
    1390         } 
    1391     } 
    1392  
    1393     return ret; 
    1394 } 
    1395  
    1396 static write_data_t *alloc_send_data(pj_ssl_sock_t *ssock, pj_size_t len) 
    1397 { 
    1398     send_buf_t *send_buf = &ssock->send_buf; 
    1399     pj_size_t avail_len, skipped_len = 0; 
    1400     char *reg1, *reg2; 
    1401     pj_size_t reg1_len, reg2_len; 
    1402     write_data_t *p; 
    1403  
    1404     /* Check buffer availability */ 
    1405     avail_len = send_buf->max_len - send_buf->len; 
    1406     if (avail_len < len) 
    1407         return NULL; 
    1408  
    1409     /* If buffer empty, reset start pointer and return it */ 
    1410     if (send_buf->len == 0) { 
    1411         send_buf->start = send_buf->buf; 
    1412         send_buf->len   = len; 
    1413         p = (write_data_t*)send_buf->start; 
    1414         goto init_send_data; 
    1415     } 
    1416  
    1417     /* Free space may be wrapped/splitted into two regions, so let's 
    1418      * analyze them if any region can hold the write data. */ 
    1419     reg1 = send_buf->start + send_buf->len; 
    1420     if (reg1 >= send_buf->buf + send_buf->max_len) 
    1421         reg1 -= send_buf->max_len; 
    1422         reg1_len = send_buf->max_len - send_buf->len; 
    1423     if (reg1 + reg1_len > send_buf->buf + send_buf->max_len) { 
    1424         reg1_len = send_buf->buf + send_buf->max_len - reg1; 
    1425         reg2 = send_buf->buf; 
    1426         reg2_len = send_buf->start - send_buf->buf; 
    1427     } else { 
    1428         reg2 = NULL; 
    1429         reg2_len = 0; 
    1430     } 
    1431  
    1432     /* More buffer availability check, note that the write data must be in 
    1433      * a contigue buffer. */ 
    1434     avail_len = PJ_MAX(reg1_len, reg2_len); 
    1435     if (avail_len < len) 
    1436     return NULL; 
    1437  
    1438     /* Get the data slot */ 
    1439     if (reg1_len >= len) { 
    1440         p = (write_data_t*)reg1; 
    1441     } else { 
    1442         p = (write_data_t*)reg2; 
    1443         skipped_len = reg1_len; 
    1444     } 
    1445  
    1446     /* Update buffer length */ 
    1447     send_buf->len += len + skipped_len; 
    1448  
    1449 init_send_data: 
    1450     /* Init the new send data */ 
    1451     pj_bzero(p, sizeof(*p)); 
    1452     pj_list_init(p); 
    1453     pj_list_push_back(&ssock->send_pending, p); 
    1454  
    1455     return p; 
    1456 } 
    1457  
    1458 static void free_send_data(pj_ssl_sock_t *ssock, write_data_t *wdata) 
    1459 { 
    1460     send_buf_t *buf = &ssock->send_buf; 
    1461     write_data_t *spl = &ssock->send_pending; 
    1462  
    1463     pj_assert(!pj_list_empty(&ssock->send_pending)); 
    1464  
    1465     /* Free slot from the buffer */ 
    1466     if (spl->next == wdata && spl->prev == wdata) { 
    1467     /* This is the only data, reset the buffer */ 
    1468     buf->start = buf->buf; 
    1469     buf->len = 0; 
    1470     } else if (spl->next == wdata) { 
    1471     /* This is the first data, shift start pointer of the buffer and 
    1472      * adjust the buffer length. 
    1473      */ 
    1474     buf->start = (char*)wdata->next; 
    1475     if (wdata->next > wdata) { 
    1476         buf->len -= ((char*)wdata->next - buf->start); 
    1477     } else { 
    1478         /* Overlapped */ 
    1479         pj_size_t right_len, left_len; 
    1480         right_len = buf->buf + buf->max_len - (char*)wdata; 
    1481         left_len  = (char*)wdata->next - buf->buf; 
    1482         buf->len -= (right_len + left_len); 
    1483     } 
    1484     } else if (spl->prev == wdata) { 
    1485     /* This is the last data, just adjust the buffer length */ 
    1486     if (wdata->prev < wdata) { 
    1487         pj_size_t jump_len; 
    1488         jump_len = (char*)wdata - 
    1489                ((char*)wdata->prev + wdata->prev->record_len); 
    1490         buf->len -= (wdata->record_len + jump_len); 
    1491     } else { 
    1492         /* Overlapped */ 
    1493         pj_size_t right_len, left_len; 
    1494         right_len = buf->buf + buf->max_len - 
    1495             ((char*)wdata->prev + wdata->prev->record_len); 
    1496         left_len  = (char*)wdata + wdata->record_len - buf->buf; 
    1497         buf->len -= (right_len + left_len); 
    1498     } 
    1499     } 
    1500     /* For data in the middle buffer, just do nothing on the buffer. The slot 
    1501      * will be freed later when freeing the first/last data. */ 
    1502  
    1503     /* Remove the data from send pending list */ 
    1504     pj_list_erase(wdata); 
    1505 } 
    1506  
    1507 #if 0 
    1508 /* Just for testing send buffer alloc/free */ 
    1509 #include <pj/rand.h> 
    1510 pj_status_t pj_ssl_sock_ossl_test_send_buf(pj_pool_t *pool) 
    1511 { 
    1512     enum { MAX_CHUNK_NUM = 20 }; 
    1513     unsigned chunk_size, chunk_cnt, i; 
    1514     write_data_t *wdata[MAX_CHUNK_NUM] = {0}; 
    1515     pj_time_val now; 
    1516     pj_ssl_sock_t *ssock = NULL; 
    1517     pj_ssl_sock_param param; 
    1518     pj_status_t status; 
    1519  
    1520     pj_gettimeofday(&now); 
    1521     pj_srand((unsigned)now.sec); 
    1522  
    1523     pj_ssl_sock_param_default(&param); 
    1524     status = pj_ssl_sock_create(pool, &param, &ssock); 
    1525     if (status != PJ_SUCCESS) { 
    1526         return status; 
    1527     } 
    1528  
    1529     if (ssock->send_buf.max_len == 0) { 
    1530         ssock->send_buf.buf = (char *) 
    1531                               pj_pool_alloc(ssock->pool, 
    1532                                             ssock->param.send_buffer_size); 
    1533         ssock->send_buf.max_len = ssock->param.send_buffer_size; 
    1534         ssock->send_buf.start = ssock->send_buf.buf; 
    1535         ssock->send_buf.len = 0; 
    1536     } 
    1537  
    1538     chunk_size = ssock->param.send_buffer_size / MAX_CHUNK_NUM / 2; 
    1539     chunk_cnt = 0; 
    1540     for (i = 0; i < MAX_CHUNK_NUM; i++) { 
    1541         wdata[i] = alloc_send_data(ssock, pj_rand() % chunk_size + 321); 
    1542         if (wdata[i]) 
    1543             chunk_cnt++; 
    1544         else 
    1545             break; 
    1546     } 
    1547  
    1548     while (chunk_cnt) { 
    1549         i = pj_rand() % MAX_CHUNK_NUM; 
    1550         if (wdata[i]) { 
    1551             free_send_data(ssock, wdata[i]); 
    1552             wdata[i] = NULL; 
    1553             chunk_cnt--; 
    1554         } 
    1555     } 
    1556  
    1557     if (ssock->send_buf.len != 0) 
    1558         status = PJ_EBUG; 
    1559  
    1560     pj_ssl_sock_close(ssock); 
    1561     return status; 
    1562 } 
    1563 #endif 
    1564  
    1565 /* Flush write circular buffer to network socket. */ 
    1566 static pj_status_t flush_circ_buf_output(pj_ssl_sock_t *ssock, 
    1567                                          pj_ioqueue_op_key_t *send_key, 
    1568                                          pj_size_t orig_len, unsigned flags) 
    1569 { 
    1570     pj_ssize_t len; 
    1571     write_data_t *wdata; 
    1572     pj_size_t needed_len; 
    1573     pj_status_t status; 
    1574  
    1575     pj_lock_acquire(ssock->circ_buf_output_mutex); 
    1576  
    1577     /* Check if there is data in the circular buffer, flush it if any */ 
    1578     if (circ_empty(&ssock->circ_buf_output)) { 
    1579         pj_lock_release(ssock->circ_buf_output_mutex); 
    1580  
    1581         return PJ_SUCCESS; 
    1582     } 
    1583  
    1584     len = circ_size(&ssock->circ_buf_output); 
    1585  
    1586     /* Calculate buffer size needed, and align it to 8 */ 
    1587     needed_len = len + sizeof(write_data_t); 
    1588     needed_len = ((needed_len + 7) >> 3) << 3; 
    1589  
    1590     /* Allocate buffer for send data */ 
    1591     wdata = alloc_send_data(ssock, needed_len); 
    1592     if (wdata == NULL) { 
    1593         pj_lock_release(ssock->circ_buf_output_mutex); 
    1594         return PJ_ENOMEM; 
    1595     } 
    1596  
    1597     /* Copy the data and set its properties into the send data */ 
    1598     pj_ioqueue_op_key_init(&wdata->key, sizeof(pj_ioqueue_op_key_t)); 
    1599     wdata->key.user_data = wdata; 
    1600     wdata->app_key = send_key; 
    1601     wdata->record_len = needed_len; 
    1602     wdata->data_len = len; 
    1603     wdata->plain_data_len = orig_len; 
    1604     wdata->flags = flags; 
    1605     circ_read(&ssock->circ_buf_output, (pj_uint8_t *)&wdata->data, len); 
    1606  
    1607     /* Ticket #1573: Don't hold mutex while calling PJLIB socket send(). */ 
    1608     pj_lock_release(ssock->circ_buf_output_mutex); 
    1609  
    1610     /* Send it */ 
    1611     if (ssock->param.sock_type == pj_SOCK_STREAM()) { 
    1612         status = pj_activesock_send(ssock->asock, &wdata->key, 
    1613                                     wdata->data.content, &len, 
    1614                                     flags); 
    1615     } else { 
    1616         status = pj_activesock_sendto(ssock->asock, &wdata->key, 
    1617                                       wdata->data.content, &len, 
    1618                                       flags, 
    1619                                       (pj_sockaddr_t*)&ssock->rem_addr, 
    1620                                       ssock->addr_len); 
    1621     } 
    1622  
    1623     if (status != PJ_EPENDING) { 
    1624         /* When the sending is not pending, remove the wdata from send 
    1625          * pending list. */ 
    1626         pj_lock_acquire(ssock->circ_buf_output_mutex); 
    1627         free_send_data(ssock, wdata); 
    1628         pj_lock_release(ssock->circ_buf_output_mutex); 
    1629     } 
    1630  
    1631     return status; 
    1632 } 
    1633  
    1634 static void on_timer(pj_timer_heap_t *th, struct pj_timer_entry *te) 
    1635 { 
    1636     pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)te->user_data; 
    1637     int timer_id = te->id; 
    1638  
    1639     te->id = TIMER_NONE; 
    1640  
    1641     PJ_UNUSED_ARG(th); 
    1642  
    1643     switch (timer_id) { 
    1644     case TIMER_HANDSHAKE_TIMEOUT: 
    1645         PJ_LOG(1, (ssock->pool->obj_name, "TLS timeout after %d.%ds", 
    1646                    ssock->param.timeout.sec, ssock->param.timeout.msec)); 
    1647  
    1648         on_handshake_complete(ssock, PJ_ETIMEDOUT); 
    1649         break; 
    1650     case TIMER_CLOSE: 
    1651         pj_ssl_sock_close(ssock); 
    1652         break; 
    1653     default: 
    1654         pj_assert(!"Unknown timer"); 
    1655         break; 
    1656     } 
    1657 } 
    1658  
     1110                       "gnutls_server_name_set() failed: %s", 
     1111                       gnutls_strerror(ret))); 
     1112        } 
     1113    } 
     1114} 
    16591115 
    16601116/* Try to perform an asynchronous handshake */ 
    1661 static pj_status_t tls_try_handshake(pj_ssl_sock_t *ssock) 
    1662 { 
     1117static pj_status_t ssl_do_handshake(pj_ssl_sock_t *ssock) 
     1118{ 
     1119    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    16631120    int ret; 
    16641121    pj_status_t status; 
    16651122 
    16661123    /* Perform SSL handshake */ 
    1667     ret = gnutls_handshake(ssock->session); 
     1124    ret = gnutls_handshake(gssock->session); 
    16681125 
    16691126    status = flush_circ_buf_output(ssock, &ssock->handshake_op_key, 0, 0); 
     
    16731130    if (ret == GNUTLS_E_SUCCESS) { 
    16741131        /* System are GO */ 
    1675         ssock->connection_state = TLS_STATE_ESTABLISHED; 
     1132        ssock->ssl_state = SSL_STATE_ESTABLISHED; 
    16761133        status = PJ_SUCCESS; 
    16771134    } else if (!gnutls_error_is_fatal(ret)) { 
     
    16881145} 
    16891146 
    1690  
    1691 /* 
    1692  ******************************************************************* 
    1693  * Active socket callbacks. 
    1694  ******************************************************************* 
    1695  */ 
    1696  
    1697 /* PJ_TRUE asks the socket to read more data, PJ_FALSE takes it off the queue */ 
    1698 static pj_bool_t asock_on_data_read(pj_activesock_t *asock, void *data, 
    1699                                     pj_size_t size, pj_status_t status, 
    1700                                     pj_size_t *remainder) 
    1701 { 
    1702     pj_ssl_sock_t *ssock = (pj_ssl_sock_t *) 
    1703                            pj_activesock_get_user_data(asock); 
    1704  
    1705     pj_size_t app_remainder = 0; 
    1706  
    1707     if (data && size > 0) { 
    1708         /* Push data into input circular buffer (for GnuTLS) */ 
    1709         pj_lock_acquire(ssock->circ_buf_input_mutex); 
    1710         circ_write(&ssock->circ_buf_input, data, size); 
    1711         pj_lock_release(ssock->circ_buf_input_mutex); 
    1712     } 
    1713  
    1714     /* Check if SSL handshake hasn't finished yet */ 
    1715     if (ssock->connection_state == TLS_STATE_HANDSHAKING) { 
    1716         pj_bool_t ret = PJ_TRUE; 
    1717  
    1718         if (status == PJ_SUCCESS) 
    1719             status = tls_try_handshake(ssock); 
    1720  
    1721         /* Not pending is either success or failed */ 
    1722         if (status != PJ_EPENDING) 
    1723             ret = on_handshake_complete(ssock, status); 
    1724  
    1725         return ret; 
    1726     } 
    1727  
    1728     /* See if there is any decrypted data for the application */ 
    1729     if (ssock->read_started) { 
    1730         do { 
    1731             /* Get read data structure at the end of the data */ 
    1732             read_data_t *app_read_data = 
    1733                 *(OFFSET_OF_READ_DATA_PTR(ssock, data)); 
    1734             int app_data_size = (int)(ssock->read_size - app_read_data->len); 
    1735  
    1736             /* Decrypt received data using GnuTLS (will read our input 
    1737              * circular buffer) */ 
    1738             int decrypted_size = gnutls_record_recv(ssock->session, 
    1739                                         ((read_data_t *)app_read_data->data) + 
    1740                                          app_read_data->len, 
    1741                                          app_data_size); 
    1742  
    1743             if (decrypted_size > 0 || status != PJ_SUCCESS) { 
    1744                 if (ssock->param.cb.on_data_read) { 
    1745                     pj_bool_t ret; 
    1746                     app_remainder = 0; 
    1747  
    1748                     if (decrypted_size > 0) 
    1749                         app_read_data->len += decrypted_size; 
    1750  
    1751                     ret = (*ssock->param.cb.on_data_read)(ssock, 
    1752                                                           app_read_data->data, 
    1753                                                           app_read_data->len, 
    1754                                                           status, 
    1755                                                           &app_remainder); 
    1756  
    1757                     if (!ret) { 
    1758                         /* We've been destroyed */ 
    1759                         return PJ_FALSE; 
    1760                     } 
    1761  
    1762                     /* Application may have left some data to be consumed 
    1763                      * later as remainder */ 
    1764                     app_read_data->len = app_remainder; 
    1765                 } 
    1766  
    1767                 /* Active socket signalled connection closed/error, this has 
    1768                  * been signalled to the application along with any remaining 
    1769                  * buffer. So, let's just reset SSL socket now.  */ 
    1770                 if (status != PJ_SUCCESS) { 
    1771                     tls_sock_reset(ssock); 
    1772                     return PJ_FALSE; 
    1773                 } 
    1774             } else if (decrypted_size == 0) { 
    1775                 /* Nothing more to read */ 
    1776  
    1777                 return PJ_TRUE; 
    1778             } else if (decrypted_size == GNUTLS_E_AGAIN || 
    1779                        decrypted_size == GNUTLS_E_INTERRUPTED) { 
    1780                 return PJ_TRUE; 
    1781             } else if (decrypted_size == GNUTLS_E_REHANDSHAKE) { 
    1782                 /* Seems like we are renegotiating */ 
    1783                 pj_status_t try_handshake_status = tls_try_handshake(ssock); 
    1784  
    1785                 /* Not pending is either success or failed */ 
    1786                 if (try_handshake_status != PJ_EPENDING) { 
    1787                     if (!on_handshake_complete(ssock, try_handshake_status)) { 
    1788                         return PJ_FALSE; 
    1789                     } 
    1790                 } 
    1791  
    1792                 if (try_handshake_status != PJ_SUCCESS && 
    1793                     try_handshake_status != PJ_EPENDING) { 
    1794                     return PJ_FALSE; 
    1795                 } 
    1796             } else if (!gnutls_error_is_fatal(decrypted_size)) { 
    1797                 /* non-fatal error, let's just continue */ 
    1798             } else { 
    1799                 return PJ_FALSE; 
    1800             } 
    1801         } while (PJ_TRUE); 
    1802     } 
    1803  
    1804     return PJ_TRUE; 
    1805 } 
    1806  
    1807  
    1808 /* Callback every time new data is available from the active socket */ 
    1809 static pj_bool_t asock_on_data_sent(pj_activesock_t *asock, 
    1810                                     pj_ioqueue_op_key_t *send_key, 
    1811                                     pj_ssize_t sent) 
    1812 { 
    1813     pj_ssl_sock_t *ssock = (pj_ssl_sock_t *)pj_activesock_get_user_data(asock); 
    1814  
    1815     PJ_UNUSED_ARG(send_key); 
    1816     PJ_UNUSED_ARG(sent); 
    1817  
    1818     if (ssock->connection_state == TLS_STATE_HANDSHAKING) { 
    1819         /* Initial handshaking */ 
    1820         pj_status_t status = tls_try_handshake(ssock); 
    1821  
    1822         /* Not pending is either success or failed */ 
    1823         if (status != PJ_EPENDING) 
    1824             return on_handshake_complete(ssock, status); 
    1825  
    1826     } else if (send_key != &ssock->handshake_op_key) { 
    1827         /* Some data has been sent, notify application */ 
    1828         write_data_t *wdata = (write_data_t*)send_key->user_data; 
    1829         if (ssock->param.cb.on_data_sent) { 
    1830             pj_bool_t ret; 
    1831             pj_ssize_t sent_len; 
    1832  
    1833             sent_len = sent > 0 ? wdata->plain_data_len : sent; 
    1834  
    1835             ret = (*ssock->param.cb.on_data_sent)(ssock, wdata->app_key, 
    1836                                                   sent_len); 
    1837             if (!ret) { 
    1838                 /* We've been destroyed */ 
    1839                 return PJ_FALSE; 
    1840             } 
    1841         } 
    1842  
    1843         /* Update write buffer state */ 
    1844         pj_lock_acquire(ssock->circ_buf_output_mutex); 
    1845         free_send_data(ssock, wdata); 
    1846         pj_lock_release(ssock->circ_buf_output_mutex); 
     1147static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size) 
     1148{ 
     1149    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
     1150    int decrypted_size; 
     1151 
     1152    /* Decrypt received data using GnuTLS (will read our input 
     1153     * circular buffer) */ 
     1154    decrypted_size = gnutls_record_recv(gssock->session, data, *size); 
     1155    *size = 0; 
     1156    if (decrypted_size > 0) { 
     1157        *size = decrypted_size; 
     1158        return PJ_SUCCESS; 
     1159    } else if (decrypted_size == 0) { 
     1160        /* Nothing more to read */ 
     1161        return PJ_SUCCESS; 
     1162    } else if (decrypted_size == GNUTLS_E_REHANDSHAKE) { 
     1163        return PJ_EEOF; 
     1164    } else if (decrypted_size == GNUTLS_E_AGAIN || 
     1165               decrypted_size == GNUTLS_E_INTERRUPTED || 
     1166               !gnutls_error_is_fatal(decrypted_size)) 
     1167    { 
     1168        /* non-fatal error, let's just continue */ 
     1169        return PJ_SUCCESS; 
    18471170    } else { 
    1848         /* SSL re-negotiation is on-progress, just do nothing */ 
    1849         /* FIXME: check if this is valid for GnuTLS too */ 
    1850     } 
    1851  
    1852     return PJ_TRUE; 
    1853 } 
    1854  
    1855  
    1856 /* Callback every time a new connection has been accepted (server) */ 
    1857 static pj_bool_t asock_on_accept_complete(pj_activesock_t *asock, 
    1858                                           pj_sock_t newsock, 
    1859                                           const pj_sockaddr_t *src_addr, 
    1860                                           int src_addr_len) 
    1861 { 
    1862     pj_ssl_sock_t *ssock_parent = (pj_ssl_sock_t *) 
    1863                                   pj_activesock_get_user_data(asock); 
    1864  
    1865     pj_ssl_sock_t *ssock; 
    1866     pj_activesock_cb asock_cb; 
    1867     pj_activesock_cfg asock_cfg; 
    1868     unsigned int i; 
    1869     pj_status_t status; 
    1870  
    1871     PJ_UNUSED_ARG(src_addr_len); 
    1872  
    1873     /* Create new SSL socket instance */ 
    1874     status = pj_ssl_sock_create(ssock_parent->pool, 
    1875                                 &ssock_parent->newsock_param, 
    1876                                 &ssock); 
    1877     if (status != PJ_SUCCESS) 
    1878         goto on_return; 
    1879  
    1880     /* Update new SSL socket attributes */ 
    1881     ssock->sock = newsock; 
    1882     ssock->parent = ssock_parent; 
    1883     ssock->is_server = PJ_TRUE; 
    1884     if (ssock_parent->cert) { 
    1885         status = pj_ssl_sock_set_certificate(ssock, ssock->pool, 
    1886                                              ssock_parent->cert); 
    1887         if (status != PJ_SUCCESS) 
    1888             goto on_return; 
    1889     } 
    1890  
    1891     /* Apply QoS, if specified */ 
    1892     status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type, 
    1893                                 &ssock->param.qos_params, 1, 
    1894                                 ssock->pool->obj_name, NULL); 
    1895     if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error) 
    1896         goto on_return; 
    1897  
    1898     /* Update local address */ 
    1899     ssock->addr_len = src_addr_len; 
    1900     status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, 
    1901                                  &ssock->addr_len); 
    1902     if (status != PJ_SUCCESS) { 
    1903         /* This fails on few envs, e.g: win IOCP, just tolerate this and 
    1904          * use parent local address instead. 
    1905          */ 
    1906         pj_sockaddr_cp(&ssock->local_addr, &ssock_parent->local_addr); 
    1907     } 
    1908  
    1909     /* Set remote address */ 
    1910     pj_sockaddr_cp(&ssock->rem_addr, src_addr); 
    1911  
    1912     /* Create SSL context */ 
    1913     status = tls_open(ssock); 
    1914     if (status != PJ_SUCCESS) 
    1915         goto on_return; 
    1916  
    1917     /* Prepare read buffer */ 
    1918     ssock->asock_rbuf = (void **)pj_pool_calloc(ssock->pool, 
    1919                                                 ssock->param.async_cnt, 
    1920                                                 sizeof(void*)); 
    1921     if (!ssock->asock_rbuf) 
    1922         return PJ_ENOMEM; 
    1923  
    1924     for (i = 0; i < ssock->param.async_cnt; ++i) { 
    1925         ssock->asock_rbuf[i] = (void *)pj_pool_alloc( 
    1926                                             ssock->pool, 
    1927                                             ssock->param.read_buffer_size + 
    1928                                             sizeof(read_data_t*)); 
    1929         if (!ssock->asock_rbuf[i]) 
    1930             return PJ_ENOMEM; 
    1931     } 
    1932  
    1933     /* Create active socket */ 
    1934     pj_activesock_cfg_default(&asock_cfg); 
    1935     asock_cfg.async_cnt = ssock->param.async_cnt; 
    1936     asock_cfg.concurrency = ssock->param.concurrency; 
    1937     asock_cfg.whole_data = PJ_TRUE; 
    1938  
    1939     pj_bzero(&asock_cb, sizeof(asock_cb)); 
    1940     asock_cb.on_data_read = asock_on_data_read; 
    1941     asock_cb.on_data_sent = asock_on_data_sent; 
    1942  
    1943     status = pj_activesock_create(ssock->pool, 
    1944                                   ssock->sock, 
    1945                                   ssock->param.sock_type, 
    1946                                   &asock_cfg, 
    1947                                   ssock->param.ioqueue, 
    1948                                   &asock_cb, 
    1949                                   ssock, 
    1950                                   &ssock->asock); 
    1951  
    1952     if (status != PJ_SUCCESS) 
    1953         goto on_return; 
    1954  
    1955     /* Start reading */ 
    1956     status = pj_activesock_start_read2(ssock->asock, ssock->pool, 
    1957                                        (unsigned)ssock->param.read_buffer_size, 
    1958                                        ssock->asock_rbuf, 
    1959                                        PJ_IOQUEUE_ALWAYS_ASYNC); 
    1960     if (status != PJ_SUCCESS) 
    1961         goto on_return; 
    1962  
    1963     /* Prepare write/send state */ 
    1964     pj_assert(ssock->send_buf.max_len == 0); 
    1965     ssock->send_buf.buf = (char *)pj_pool_alloc(ssock->pool, 
    1966                                                 ssock->param.send_buffer_size); 
    1967     if (!ssock->send_buf.buf) 
    1968         return PJ_ENOMEM; 
    1969  
    1970     ssock->send_buf.max_len = ssock->param.send_buffer_size; 
    1971     ssock->send_buf.start = ssock->send_buf.buf; 
    1972     ssock->send_buf.len = 0; 
    1973  
    1974     /* Start handshake timer */ 
    1975     if (ssock->param.timer_heap && 
    1976         (ssock->param.timeout.sec != 0 || ssock->param.timeout.msec != 0)) { 
    1977         pj_assert(ssock->timer.id == TIMER_NONE); 
    1978         ssock->timer.id = TIMER_HANDSHAKE_TIMEOUT; 
    1979         status = pj_timer_heap_schedule(ssock->param.timer_heap, 
    1980                                         &ssock->timer, 
    1981                                         &ssock->param.timeout); 
    1982         if (status != PJ_SUCCESS) 
    1983             ssock->timer.id = TIMER_NONE; 
    1984     } 
    1985  
    1986     /* Start SSL handshake */ 
    1987     ssock->connection_state = TLS_STATE_HANDSHAKING; 
    1988  
    1989     status = tls_try_handshake(ssock); 
    1990  
    1991 on_return: 
    1992     if (ssock && status != PJ_EPENDING) 
    1993         on_handshake_complete(ssock, status); 
    1994  
    1995     /* Must return PJ_TRUE whatever happened, as active socket must 
    1996      * continue listening. 
    1997      */ 
    1998     return PJ_TRUE; 
    1999 } 
    2000  
    2001  
    2002 /* Callback every time a new connection has been completed (client) */ 
    2003 static pj_bool_t asock_on_connect_complete (pj_activesock_t *asock, 
    2004                                             pj_status_t status) 
    2005 { 
    2006     pj_ssl_sock_t *ssock = (pj_ssl_sock_t*) 
    2007                            pj_activesock_get_user_data(asock); 
    2008  
    2009     unsigned int i; 
    2010     int ret; 
    2011  
    2012     if (status != PJ_SUCCESS) 
    2013         goto on_return; 
    2014  
    2015     /* Update local address */ 
    2016     ssock->addr_len = sizeof(pj_sockaddr); 
    2017     status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, 
    2018                                  &ssock->addr_len); 
    2019     if (status != PJ_SUCCESS) 
    2020         goto on_return; 
    2021  
    2022     /* Create SSL context */ 
    2023     status = tls_open(ssock); 
    2024     if (status != PJ_SUCCESS) 
    2025         goto on_return; 
    2026  
    2027     /* Prepare read buffer */ 
    2028     ssock->asock_rbuf = (void **)pj_pool_calloc(ssock->pool, 
    2029                                                 ssock->param.async_cnt, 
    2030                                                 sizeof(void *)); 
    2031     if (!ssock->asock_rbuf) 
    2032         return PJ_ENOMEM; 
    2033  
    2034     for (i = 0; i < ssock->param.async_cnt; ++i) { 
    2035         ssock->asock_rbuf[i] = (void *)pj_pool_alloc( 
    2036                                             ssock->pool, 
    2037                                             ssock->param.read_buffer_size + 
    2038                                             sizeof(read_data_t *)); 
    2039         if (!ssock->asock_rbuf[i]) 
    2040             return PJ_ENOMEM; 
    2041     } 
    2042  
    2043     /* Start read */ 
    2044     status = pj_activesock_start_read2(ssock->asock, ssock->pool, 
    2045                                        (unsigned)ssock->param.read_buffer_size, 
    2046                                        ssock->asock_rbuf, 
    2047                                        PJ_IOQUEUE_ALWAYS_ASYNC); 
    2048     if (status != PJ_SUCCESS) 
    2049         goto on_return; 
    2050  
    2051     /* Prepare write/send state */ 
    2052     pj_assert(ssock->send_buf.max_len == 0); 
    2053     ssock->send_buf.buf = (char *)pj_pool_alloc(ssock->pool, 
    2054                                                 ssock->param.send_buffer_size); 
    2055     if (!ssock->send_buf.buf) 
    2056         return PJ_ENOMEM; 
    2057  
    2058     ssock->send_buf.max_len = ssock->param.send_buffer_size; 
    2059     ssock->send_buf.start = ssock->send_buf.buf; 
    2060     ssock->send_buf.len = 0; 
    2061  
    2062     /* Set server name to connect */ 
    2063     if (ssock->param.server_name.slen) { 
    2064         /* Server name is null terminated already */ 
    2065         ret = gnutls_server_name_set(ssock->session, GNUTLS_NAME_DNS, 
    2066                                      ssock->param.server_name.ptr, 
    2067                                      ssock->param.server_name.slen); 
    2068         if (ret < 0) { 
    2069             PJ_LOG(3, (ssock->pool->obj_name, 
    2070                        "gnutls_server_name_set() failed: %s", 
    2071                        gnutls_strerror(ret))); 
    2072         } 
    2073     } 
    2074  
    2075     /* Start handshake */ 
    2076     ssock->connection_state = TLS_STATE_HANDSHAKING; 
    2077  
    2078     status = tls_try_handshake(ssock); 
    2079     if (status != PJ_EPENDING) 
    2080         goto on_return; 
    2081  
    2082     return PJ_TRUE; 
    2083  
    2084 on_return: 
    2085     return on_handshake_complete(ssock, status); 
    2086 } 
    2087  
    2088 static void tls_ciphers_fill(void) 
    2089 { 
    2090      if (!tls_available_ciphers) { 
    2091          tls_init(); 
    2092          tls_deinit(); 
    2093      } 
    2094 } 
    2095  
    2096 /* 
    2097  ******************************************************************* 
    2098  * API 
    2099  ******************************************************************* 
    2100  */ 
    2101  
    2102 /* Load credentials from files. */ 
    2103 PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files(pj_pool_t *pool, 
    2104                                                 const pj_str_t *CA_file, 
    2105                                                 const pj_str_t *cert_file, 
    2106                                                 const pj_str_t *privkey_file, 
    2107                                                 const pj_str_t *privkey_pass, 
    2108                                                 pj_ssl_cert_t **p_cert) 
    2109 { 
    2110     return pj_ssl_cert_load_from_files2(pool, CA_file, NULL, cert_file, 
    2111                     privkey_file, privkey_pass, p_cert); 
    2112 } 
    2113  
    2114 /* Load credentials from files. */ 
    2115 PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files2( 
    2116                         pj_pool_t *pool, 
    2117                         const pj_str_t *CA_file, 
    2118                         const pj_str_t *CA_path, 
    2119                         const pj_str_t *cert_file, 
    2120                         const pj_str_t *privkey_file, 
    2121                         const pj_str_t *privkey_pass, 
    2122                         pj_ssl_cert_t **p_cert) 
    2123 { 
    2124     pj_ssl_cert_t *cert; 
    2125  
    2126     PJ_ASSERT_RETURN(pool && (CA_file || CA_path) && cert_file && 
    2127              privkey_file, 
    2128              PJ_EINVAL); 
    2129  
    2130     cert = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t); 
    2131     if (CA_file) { 
    2132         pj_strdup_with_null(pool, &cert->CA_file, CA_file); 
    2133     } 
    2134     if (CA_path) { 
    2135         pj_strdup_with_null(pool, &cert->CA_path, CA_path); 
    2136     } 
    2137     pj_strdup_with_null(pool, &cert->cert_file, cert_file); 
    2138     pj_strdup_with_null(pool, &cert->privkey_file, privkey_file); 
    2139     pj_strdup_with_null(pool, &cert->privkey_pass, privkey_pass); 
    2140  
    2141     *p_cert = cert; 
    2142  
    2143     return PJ_SUCCESS; 
    2144 } 
    2145  
    2146 PJ_DEF(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool, 
    2147                                         const pj_ssl_cert_buffer *CA_buf, 
    2148                                         const pj_ssl_cert_buffer *cert_buf, 
    2149                                         const pj_ssl_cert_buffer *privkey_buf, 
    2150                                         const pj_str_t *privkey_pass, 
    2151                                         pj_ssl_cert_t **p_cert) 
    2152 { 
    2153     pj_ssl_cert_t *cert; 
    2154  
    2155     PJ_ASSERT_RETURN(pool && CA_buf && cert_buf && privkey_buf, PJ_EINVAL); 
    2156  
    2157     cert = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t); 
    2158     pj_strdup(pool, &cert->CA_buf, CA_buf); 
    2159     pj_strdup(pool, &cert->cert_buf, cert_buf); 
    2160     pj_strdup(pool, &cert->privkey_buf, privkey_buf); 
    2161     pj_strdup_with_null(pool, &cert->privkey_pass, privkey_pass); 
    2162  
    2163     *p_cert = cert; 
    2164  
    2165     return PJ_SUCCESS; 
    2166 } 
    2167  
    2168 /* Store credentials. */ 
    2169 PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate( pj_ssl_sock_t *ssock, 
    2170                                                  pj_pool_t *pool, 
    2171                                                  const pj_ssl_cert_t *cert) 
    2172 { 
    2173     pj_ssl_cert_t *cert_; 
    2174  
    2175     PJ_ASSERT_RETURN(ssock && pool && cert, PJ_EINVAL); 
    2176  
    2177     cert_ = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t); 
    2178     pj_memcpy(cert_, cert, sizeof(cert)); 
    2179     pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file); 
    2180     pj_strdup_with_null(pool, &cert_->CA_path, &cert->CA_path); 
    2181     pj_strdup_with_null(pool, &cert_->cert_file, &cert->cert_file); 
    2182     pj_strdup_with_null(pool, &cert_->privkey_file, &cert->privkey_file); 
    2183     pj_strdup_with_null(pool, &cert_->privkey_pass, &cert->privkey_pass); 
    2184  
    2185     pj_strdup(pool, &cert_->CA_buf, &cert->CA_buf); 
    2186     pj_strdup(pool, &cert_->cert_buf, &cert->cert_buf); 
    2187     pj_strdup(pool, &cert_->privkey_buf, &cert->privkey_buf); 
    2188  
    2189     ssock->cert = cert_; 
    2190  
    2191     return PJ_SUCCESS; 
    2192 } 
    2193  
    2194  
    2195 /* Get available ciphers. */ 
    2196 PJ_DEF(pj_status_t) pj_ssl_cipher_get_availables(pj_ssl_cipher ciphers[], 
    2197                                                  unsigned *cipher_num) 
    2198 { 
    2199     unsigned int i; 
    2200  
    2201     PJ_ASSERT_RETURN(ciphers && cipher_num, PJ_EINVAL); 
    2202  
    2203     tls_ciphers_fill(); 
    2204  
    2205     if (!tls_available_ciphers) { 
    2206         *cipher_num = 0; 
    2207         return PJ_ENOTFOUND; 
    2208     } 
    2209  
    2210     *cipher_num = PJ_MIN(*cipher_num, tls_available_ciphers); 
    2211  
    2212     for (i = 0; i < *cipher_num; ++i) 
    2213         ciphers[i] = tls_ciphers[i].id; 
    2214  
    2215     return PJ_SUCCESS; 
    2216 } 
    2217  
    2218  
    2219 /* Get cipher name string. */ 
    2220 PJ_DEF(const char *)pj_ssl_cipher_name(pj_ssl_cipher cipher) 
    2221 { 
    2222     unsigned int i; 
    2223  
    2224     tls_ciphers_fill(); 
    2225  
    2226     for (i = 0; i < tls_available_ciphers; ++i) { 
    2227         if (cipher == tls_ciphers[i].id) 
    2228             return tls_ciphers[i].name; 
    2229     } 
    2230  
    2231     return NULL; 
    2232 } 
    2233  
    2234  
    2235 /* Get cipher identifier. */ 
    2236 PJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name) 
    2237 { 
    2238     unsigned int i; 
    2239  
    2240     tls_ciphers_fill(); 
    2241  
    2242     for (i = 0; i < tls_available_ciphers; ++i) { 
    2243         if (!pj_ansi_stricmp(tls_ciphers[i].name, cipher_name)) 
    2244             return tls_ciphers[i].id; 
    2245     } 
    2246  
    2247     return PJ_TLS_UNKNOWN_CIPHER; 
    2248 } 
    2249  
    2250  
    2251 /* Check if the specified cipher is supported by the TLS backend. */ 
    2252 PJ_DEF(pj_bool_t) pj_ssl_cipher_is_supported(pj_ssl_cipher cipher) 
    2253 { 
    2254     unsigned int i; 
    2255  
    2256     tls_ciphers_fill(); 
    2257  
    2258     for (i = 0; i < tls_available_ciphers; ++i) { 
    2259         if (cipher == tls_ciphers[i].id) 
    2260             return PJ_TRUE; 
    2261     } 
    2262  
    2263     return PJ_FALSE; 
    2264 } 
    2265  
    2266 /* Create SSL socket instance. */ 
    2267 PJ_DEF(pj_status_t) pj_ssl_sock_create(pj_pool_t *pool, 
    2268                                        const pj_ssl_sock_param *param, 
    2269                                        pj_ssl_sock_t **p_ssock) 
    2270 { 
    2271     pj_ssl_sock_t *ssock; 
    2272     pj_status_t status; 
    2273  
    2274     PJ_ASSERT_RETURN(pool && param && p_ssock, PJ_EINVAL); 
    2275     PJ_ASSERT_RETURN(param->sock_type == pj_SOCK_STREAM(), PJ_ENOTSUP); 
    2276  
    2277     pool = pj_pool_create(pool->factory, "tls%p", 512, 512, NULL); 
    2278  
    2279     /* Create secure socket */ 
    2280     ssock = PJ_POOL_ZALLOC_T(pool, pj_ssl_sock_t); 
    2281     ssock->pool = pool; 
    2282     ssock->sock = PJ_INVALID_SOCKET; 
    2283     ssock->connection_state = TLS_STATE_NULL; 
    2284     pj_list_init(&ssock->write_pending); 
    2285     pj_list_init(&ssock->write_pending_empty); 
    2286     pj_list_init(&ssock->send_pending); 
    2287     pj_timer_entry_init(&ssock->timer, 0, ssock, &on_timer); 
    2288     pj_ioqueue_op_key_init(&ssock->handshake_op_key, 
    2289                            sizeof(pj_ioqueue_op_key_t)); 
    2290  
    2291     /* Create secure socket mutex */ 
    2292     status = pj_lock_create_recursive_mutex(pool, pool->obj_name, 
    2293                                             &ssock->circ_buf_output_mutex); 
    2294     if (status != PJ_SUCCESS) 
    2295         return status; 
    2296  
    2297     /* Create input circular buffer mutex */ 
    2298     status = pj_lock_create_simple_mutex(pool, pool->obj_name, 
    2299                                          &ssock->circ_buf_input_mutex); 
    2300     if (status != PJ_SUCCESS) 
    2301         return status; 
    2302  
    2303     /* Create output circular buffer mutex */ 
    2304     status = pj_lock_create_simple_mutex(pool, pool->obj_name, 
    2305                                          &ssock->circ_buf_output_mutex); 
    2306     if (status != PJ_SUCCESS) 
    2307         return status; 
    2308  
    2309     /* Init secure socket param */ 
    2310     ssock->param = *param; 
    2311     ssock->param.read_buffer_size = ((ssock->param.read_buffer_size + 7) >> 3) 
    2312                                      << 3; 
    2313  
    2314     if (param->ciphers_num > 0) { 
    2315         unsigned int i; 
    2316         ssock->param.ciphers = (pj_ssl_cipher *) 
    2317                                pj_pool_calloc(pool, param->ciphers_num, 
    2318                                               sizeof(pj_ssl_cipher)); 
    2319         if (!ssock->param.ciphers) 
    2320             return PJ_ENOMEM; 
    2321  
    2322         for (i = 0; i < param->ciphers_num; ++i) 
    2323             ssock->param.ciphers[i] = param->ciphers[i]; 
    2324     } 
    2325  
    2326     /* Server name must be null-terminated */ 
    2327     pj_strdup_with_null(pool, &ssock->param.server_name, &param->server_name); 
    2328  
    2329     /* Finally */ 
    2330     *p_ssock = ssock; 
    2331  
    2332     return PJ_SUCCESS; 
    2333 } 
    2334  
    2335  
    2336 /* 
    2337  * Close the secure socket. This will unregister the socket from the 
    2338  * ioqueue and ultimately close the socket. 
    2339  */ 
    2340 PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock) 
    2341 { 
    2342     pj_pool_t *pool; 
    2343  
    2344     PJ_ASSERT_RETURN(ssock, PJ_EINVAL); 
    2345  
    2346     if (!ssock->pool) 
    2347         return PJ_SUCCESS; 
    2348  
    2349     if (ssock->timer.id != TIMER_NONE) { 
    2350         pj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer); 
    2351         ssock->timer.id = TIMER_NONE; 
    2352     } 
    2353  
    2354     tls_sock_reset(ssock); 
    2355  
    2356     pj_lock_destroy(ssock->circ_buf_output_mutex); 
    2357     pj_lock_destroy(ssock->circ_buf_input_mutex); 
    2358  
    2359     pool = ssock->pool; 
    2360     ssock->pool = NULL; 
    2361     if (pool) 
    2362         pj_pool_release(pool); 
    2363  
    2364     return PJ_SUCCESS; 
    2365 } 
    2366  
    2367  
    2368 /* Associate arbitrary data with the secure socket. */ 
    2369 PJ_DEF(pj_status_t) pj_ssl_sock_set_user_data(pj_ssl_sock_t *ssock, 
    2370                                               void *user_data) 
    2371 { 
    2372     PJ_ASSERT_RETURN(ssock, PJ_EINVAL); 
    2373  
    2374     ssock->param.user_data = user_data; 
    2375     return PJ_SUCCESS; 
    2376 } 
    2377  
    2378  
    2379 /* Retrieve the user data previously associated with this secure socket. */ 
    2380 PJ_DEF(void *)pj_ssl_sock_get_user_data(pj_ssl_sock_t *ssock) 
    2381 { 
    2382     PJ_ASSERT_RETURN(ssock, NULL); 
    2383  
    2384     return ssock->param.user_data; 
    2385 } 
    2386  
    2387  
    2388 /* Retrieve the local address and port used by specified SSL socket. */ 
    2389 PJ_DEF(pj_status_t) pj_ssl_sock_get_info (pj_ssl_sock_t *ssock, 
    2390                                           pj_ssl_sock_info *info) 
    2391 { 
    2392     pj_bzero(info, sizeof(*info)); 
    2393  
    2394     /* Established flag */ 
    2395     info->established = (ssock->connection_state == TLS_STATE_ESTABLISHED); 
    2396  
    2397     /* Protocol */ 
    2398     info->proto = ssock->param.proto; 
    2399  
    2400     /* Local address */ 
    2401     pj_sockaddr_cp(&info->local_addr, &ssock->local_addr); 
    2402  
    2403     if (info->established) { 
    2404         int i; 
    2405         gnutls_cipher_algorithm_t lookup; 
    2406         gnutls_cipher_algorithm_t cipher; 
    2407  
    2408         /* Current cipher */ 
    2409         cipher = gnutls_cipher_get(ssock->session); 
    2410         for (i = 0; ; i++) { 
    2411             unsigned char id[2]; 
    2412             const char *suite = gnutls_cipher_suite_info(i,(unsigned char *)id, 
    2413                                                          NULL, &lookup, NULL, 
    2414                                                          NULL); 
    2415             if (suite) { 
    2416                 if (lookup == cipher) { 
    2417                     info->cipher = (pj_uint32_t) ((id[0] << 8) | id[1]); 
    2418                     break; 
    2419                 } 
    2420             } else 
    2421                 break; 
    2422         } 
    2423  
    2424         /* Remote address */ 
    2425         pj_sockaddr_cp(&info->remote_addr, &ssock->rem_addr); 
    2426  
    2427         /* Certificates info */ 
    2428         info->local_cert_info = &ssock->local_cert_info; 
    2429         info->remote_cert_info = &ssock->remote_cert_info; 
    2430  
    2431         /* Verification status */ 
    2432         info->verify_status = ssock->verify_status; 
    2433     } 
    2434  
    2435     /* Last known GnuTLS error code */ 
    2436     info->last_native_err = ssock->last_err; 
    2437  
    2438     return PJ_SUCCESS; 
    2439 } 
    2440  
    2441  
    2442 /* Starts read operation on this secure socket. */ 
    2443 PJ_DEF(pj_status_t) pj_ssl_sock_start_read(pj_ssl_sock_t *ssock, 
    2444                                            pj_pool_t *pool, 
    2445                                            unsigned buff_size, 
    2446                                            pj_uint32_t flags) 
    2447 { 
    2448     void **readbuf; 
    2449     unsigned int i; 
    2450  
    2451     PJ_ASSERT_RETURN(ssock && pool && buff_size, PJ_EINVAL); 
    2452     PJ_ASSERT_RETURN(ssock->connection_state == TLS_STATE_ESTABLISHED, 
    2453                      PJ_EINVALIDOP); 
    2454  
    2455     readbuf = (void**) pj_pool_calloc(pool, ssock->param.async_cnt, 
    2456                                       sizeof(void *)); 
    2457     if (!readbuf) 
    2458         return PJ_ENOMEM; 
    2459  
    2460     for (i = 0; i < ssock->param.async_cnt; ++i) { 
    2461         readbuf[i] = pj_pool_alloc(pool, buff_size); 
    2462         if (!readbuf[i]) 
    2463             return PJ_ENOMEM; 
    2464     } 
    2465  
    2466     return pj_ssl_sock_start_read2(ssock, pool, buff_size, readbuf, flags); 
    2467 } 
    2468  
    2469  
    2470 /* 
    2471  * Same as #pj_ssl_sock_start_read(), except that the application 
    2472  * supplies the buffers for the read operation so that the acive socket 
    2473  * does not have to allocate the buffers. 
    2474  */ 
    2475 PJ_DEF(pj_status_t) pj_ssl_sock_start_read2 (pj_ssl_sock_t *ssock, 
    2476                                              pj_pool_t *pool, 
    2477                                              unsigned buff_size, 
    2478                                              void *readbuf[], 
    2479                                              pj_uint32_t flags) 
    2480 { 
    2481     unsigned int i; 
    2482  
    2483     PJ_ASSERT_RETURN(ssock && pool && buff_size && readbuf, PJ_EINVAL); 
    2484     PJ_ASSERT_RETURN(ssock->connection_state == TLS_STATE_ESTABLISHED, 
    2485                      PJ_EINVALIDOP); 
    2486  
    2487     /* Create SSL socket read buffer */ 
    2488     ssock->ssock_rbuf = (read_data_t*)pj_pool_calloc(pool, 
    2489                                                      ssock->param.async_cnt, 
    2490                                                      sizeof(read_data_t)); 
    2491     if (!ssock->ssock_rbuf) 
    2492         return PJ_ENOMEM; 
    2493  
    2494     /* Store SSL socket read buffer pointer in the activesock read buffer */ 
    2495     for (i = 0; i < ssock->param.async_cnt; ++i) { 
    2496         read_data_t **p_ssock_rbuf = 
    2497                         OFFSET_OF_READ_DATA_PTR(ssock, ssock->asock_rbuf[i]); 
    2498  
    2499         ssock->ssock_rbuf[i].data = readbuf[i]; 
    2500         ssock->ssock_rbuf[i].len = 0; 
    2501  
    2502         *p_ssock_rbuf = &ssock->ssock_rbuf[i]; 
    2503     } 
    2504  
    2505     ssock->read_size = buff_size; 
    2506     ssock->read_started = PJ_TRUE; 
    2507     ssock->read_flags = flags; 
    2508  
    2509     return PJ_SUCCESS; 
    2510 } 
    2511  
    2512  
    2513 /* 
    2514  * Same as pj_ssl_sock_start_read(), except that this function is used 
    2515  * only for datagram sockets, and it will trigger \a on_data_recvfrom() 
    2516  * callback instead. 
    2517  */ 
    2518 PJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom (pj_ssl_sock_t *ssock, 
    2519                                                 pj_pool_t *pool, 
    2520                                                 unsigned buff_size, 
    2521                                                 pj_uint32_t flags) 
    2522 { 
    2523     PJ_UNUSED_ARG(ssock); 
    2524     PJ_UNUSED_ARG(pool); 
    2525     PJ_UNUSED_ARG(buff_size); 
    2526     PJ_UNUSED_ARG(flags); 
    2527  
    2528     return PJ_ENOTSUP; 
    2529 } 
    2530  
    2531  
    2532 /* 
    2533  * Same as #pj_ssl_sock_start_recvfrom() except that the recvfrom() 
    2534  * operation takes the buffer from the argument rather than creating 
    2535  * new ones. 
    2536  */ 
    2537 PJ_DEF(pj_status_t) pj_ssl_sock_start_recvfrom2 (pj_ssl_sock_t *ssock, 
    2538                                                  pj_pool_t *pool, 
    2539                                                  unsigned buff_size, 
    2540                                                  void *readbuf[], 
    2541                                                  pj_uint32_t flags) 
    2542 { 
    2543     PJ_UNUSED_ARG(ssock); 
    2544     PJ_UNUSED_ARG(pool); 
    2545     PJ_UNUSED_ARG(buff_size); 
    2546     PJ_UNUSED_ARG(readbuf); 
    2547     PJ_UNUSED_ARG(flags); 
    2548  
    2549     return PJ_ENOTSUP; 
    2550 } 
    2551  
     1171        return PJ_ECANCELLED; 
     1172    } 
     1173} 
    25521174 
    25531175/* 
     
    25561178 * sending data should be delayed until re-negotiation is completed. 
    25571179 */ 
    2558 static pj_status_t tls_write(pj_ssl_sock_t *ssock, 
    2559                              pj_ioqueue_op_key_t *send_key, 
    2560                              const void *data, pj_ssize_t size, unsigned flags) 
    2561 { 
    2562     pj_status_t status; 
    2563     int nwritten; 
     1180static pj_status_t ssl_write(pj_ssl_sock_t *ssock, const void *data, 
     1181                             pj_ssize_t size, int *nwritten) 
     1182{ 
     1183    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
     1184    int nwritten_; 
    25641185    pj_ssize_t total_written = 0; 
    25651186 
     
    25711192    while (total_written < size) { 
    25721193        /* Try encrypting using GnuTLS */ 
    2573         nwritten = gnutls_record_send(ssock->session, 
     1194        nwritten_ = gnutls_record_send(gssock->session, 
    25741195                                      ((read_data_t *)data) + total_written, 
    2575                                       size); 
    2576  
    2577         if (nwritten > 0) { 
     1196                                      size - total_written); 
     1197 
     1198        if (nwritten_ > 0) { 
    25781199            /* Good, some data was encrypted and written */ 
    2579             total_written += nwritten; 
     1200            total_written += nwritten_; 
    25801201        } else { 
    25811202            /* Normally we would have to retry record_send but our internal 
     
    25831204             * We will just try again later, although this should never happen. 
    25841205             */ 
    2585             return tls_status_from_err(ssock, nwritten); 
     1206            *nwritten = nwritten_; 
     1207            return tls_status_from_err(ssock, nwritten_); 
    25861208        } 
    25871209    } 
     
    25891211    /* All encrypted data is written to the output circular buffer; 
    25901212     * now send it on the socket (or notify problem). */ 
    2591     if (total_written == size) 
    2592         status = flush_circ_buf_output(ssock, send_key, size, flags); 
    2593     else 
    2594         status = PJ_ENOMEM; 
    2595  
    2596     return status; 
    2597 } 
    2598  
    2599  
    2600 /* Flush delayed data sending in the write pending list. */ 
    2601 static pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock) 
    2602 { 
    2603     /* Check for another ongoing flush */ 
    2604     if (ssock->flushing_write_pend) { 
    2605         return PJ_EBUSY; 
    2606     } 
    2607  
    2608     pj_lock_acquire(ssock->circ_buf_output_mutex); 
    2609  
    2610     /* Again, check for another ongoing flush */ 
    2611     if (ssock->flushing_write_pend) { 
    2612         pj_lock_release(ssock->circ_buf_output_mutex); 
    2613         return PJ_EBUSY; 
    2614     } 
    2615  
    2616     /* Set ongoing flush flag */ 
    2617     ssock->flushing_write_pend = PJ_TRUE; 
    2618  
    2619     while (!pj_list_empty(&ssock->write_pending)) { 
    2620         write_data_t *wp; 
    2621         pj_status_t status; 
    2622  
    2623         wp = ssock->write_pending.next; 
    2624  
    2625         /* Ticket #1573: Don't hold mutex while calling socket send. */ 
    2626         pj_lock_release(ssock->circ_buf_output_mutex); 
    2627  
    2628         status = tls_write(ssock, &wp->key, wp->data.ptr, 
    2629                            wp->plain_data_len, wp->flags); 
    2630         if (status != PJ_SUCCESS) { 
    2631             /* Reset ongoing flush flag first. */ 
    2632             ssock->flushing_write_pend = PJ_FALSE; 
    2633             return status; 
    2634         } 
    2635  
    2636         pj_lock_acquire(ssock->circ_buf_output_mutex); 
    2637         pj_list_erase(wp); 
    2638         pj_list_push_back(&ssock->write_pending_empty, wp); 
    2639     } 
    2640  
    2641     /* Reset ongoing flush flag */ 
    2642     ssock->flushing_write_pend = PJ_FALSE; 
    2643  
    2644     pj_lock_release(ssock->circ_buf_output_mutex); 
    2645  
     1213    *nwritten = total_written; 
    26461214    return PJ_SUCCESS; 
    26471215} 
    26481216 
    2649  
    2650 /* Sending is delayed, push back the sending data into pending list. */ 
    2651 static pj_status_t delay_send(pj_ssl_sock_t *ssock, 
    2652                               pj_ioqueue_op_key_t *send_key, 
    2653                               const void *data, pj_ssize_t size, 
    2654                               unsigned flags) 
    2655 { 
    2656     write_data_t *wp; 
    2657  
    2658     pj_lock_acquire(ssock->circ_buf_output_mutex); 
    2659  
    2660     /* Init write pending instance */ 
    2661     if (!pj_list_empty(&ssock->write_pending_empty)) { 
    2662         wp = ssock->write_pending_empty.next; 
    2663         pj_list_erase(wp); 
    2664     } else { 
    2665         wp = PJ_POOL_ZALLOC_T(ssock->pool, write_data_t); 
    2666     } 
    2667  
    2668     wp->app_key = send_key; 
    2669     wp->plain_data_len = size; 
    2670     wp->data.ptr = data; 
    2671     wp->flags = flags; 
    2672  
    2673     pj_list_push_back(&ssock->write_pending, wp); 
    2674  
    2675     pj_lock_release(ssock->circ_buf_output_mutex); 
    2676  
    2677     /* Must return PJ_EPENDING */ 
    2678     return PJ_EPENDING; 
    2679 } 
    2680  
    2681  
    2682 /** 
    2683  * Send data using the socket. 
    2684  */ 
    2685 PJ_DEF(pj_status_t) pj_ssl_sock_send(pj_ssl_sock_t *ssock, 
    2686                                      pj_ioqueue_op_key_t *send_key, 
    2687                                      const void *data, pj_ssize_t *size, 
    2688                                      unsigned flags) 
    2689 { 
    2690     pj_status_t status; 
    2691  
    2692     PJ_ASSERT_RETURN(ssock && data && size && (*size > 0), PJ_EINVAL); 
    2693     PJ_ASSERT_RETURN(ssock->connection_state==TLS_STATE_ESTABLISHED, 
    2694                      PJ_EINVALIDOP); 
    2695  
    2696     /* Flush delayed send first. Sending data might be delayed when 
    2697      * re-negotiation is on-progress. */ 
    2698     status = flush_delayed_send(ssock); 
    2699     if (status == PJ_EBUSY) { 
    2700         /* Re-negotiation or flushing is on progress, delay sending */ 
    2701         status = delay_send(ssock, send_key, data, *size, flags); 
    2702         goto on_return; 
    2703     } else if (status != PJ_SUCCESS) { 
    2704         goto on_return; 
    2705     } 
    2706  
    2707     /* Write data to SSL */ 
    2708     status = tls_write(ssock, send_key, data, *size, flags); 
    2709     if (status == PJ_EBUSY) { 
    2710         /* Re-negotiation is on progress, delay sending */ 
    2711         status = delay_send(ssock, send_key, data, *size, flags); 
    2712     } 
    2713  
    2714 on_return: 
    2715     return status; 
    2716 } 
    2717  
    2718  
    2719 /** 
    2720  * Send datagram using the socket. 
    2721  */ 
    2722 PJ_DEF(pj_status_t) pj_ssl_sock_sendto (pj_ssl_sock_t *ssock, 
    2723                                         pj_ioqueue_op_key_t *send_key, 
    2724                                         const void *data, pj_ssize_t *size, 
    2725                                         unsigned flags, 
    2726                                         const pj_sockaddr_t *addr, int addr_len) 
    2727 { 
    2728     PJ_UNUSED_ARG(ssock); 
    2729     PJ_UNUSED_ARG(send_key); 
    2730     PJ_UNUSED_ARG(data); 
    2731     PJ_UNUSED_ARG(size); 
    2732     PJ_UNUSED_ARG(flags); 
    2733     PJ_UNUSED_ARG(addr); 
    2734     PJ_UNUSED_ARG(addr_len); 
    2735  
    2736     return PJ_ENOTSUP; 
    2737 } 
    2738  
    2739 /** 
    2740  * Starts asynchronous socket accept() operations on this secure socket. 
    2741  */ 
    2742 PJ_DEF(pj_status_t) pj_ssl_sock_start_accept (pj_ssl_sock_t *ssock, 
    2743                           pj_pool_t *pool, 
    2744                           const pj_sockaddr_t *localaddr, 
    2745                           int addr_len) 
    2746 { 
    2747     return pj_ssl_sock_start_accept2(ssock, pool, localaddr, addr_len, 
    2748                          &ssock->param); 
    2749 } 
    2750  
    2751 /** 
    2752  * Starts asynchronous socket accept() operations on this secure socket. 
    2753  */ 
    2754 PJ_DEF(pj_status_t) 
    2755 pj_ssl_sock_start_accept2 (pj_ssl_sock_t *ssock, 
    2756                            pj_pool_t *pool, 
    2757                            const pj_sockaddr_t *localaddr, 
    2758                            int addr_len, 
    2759                            const pj_ssl_sock_param *newsock_param) 
    2760 { 
    2761     pj_activesock_cb asock_cb; 
    2762     pj_activesock_cfg asock_cfg; 
    2763     pj_status_t status; 
    2764  
    2765     PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL); 
    2766  
    2767     /* Verify new socket parameters */ 
    2768     if (newsock_param->grp_lock != ssock->param.grp_lock || 
    2769         newsock_param->sock_af != ssock->param.sock_af || 
    2770         newsock_param->sock_type != ssock->param.sock_type) 
    2771     { 
    2772         return PJ_EINVAL; 
    2773     } 
    2774  
    2775     /* Create socket */ 
    2776     status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0, 
    2777                             &ssock->sock); 
    2778     if (status != PJ_SUCCESS) 
    2779         goto on_error; 
    2780  
    2781     /* Apply SO_REUSEADDR */ 
    2782     if (ssock->param.reuse_addr) { 
    2783         int enabled = 1; 
    2784         status = pj_sock_setsockopt(ssock->sock, pj_SOL_SOCKET(), 
    2785                                     pj_SO_REUSEADDR(), 
    2786                                     &enabled, sizeof(enabled)); 
    2787         if (status != PJ_SUCCESS) { 
    2788             PJ_PERROR(4,(ssock->pool->obj_name, status, 
    2789                          "Warning: error applying SO_REUSEADDR")); 
    2790         } 
    2791     } 
    2792  
    2793     /* Apply QoS, if specified */ 
    2794     status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type, 
    2795                                 &ssock->param.qos_params, 2, 
    2796                                 ssock->pool->obj_name, NULL); 
    2797     if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error) 
    2798         goto on_error; 
    2799  
    2800     /* Bind socket */ 
    2801     status = pj_sock_bind(ssock->sock, localaddr, addr_len); 
    2802     if (status != PJ_SUCCESS) 
    2803         goto on_error; 
    2804  
    2805     /* Start listening to the address */ 
    2806     status = pj_sock_listen(ssock->sock, PJ_SOMAXCONN); 
    2807     if (status != PJ_SUCCESS) 
    2808         goto on_error; 
    2809  
    2810     /* Create active socket */ 
    2811     pj_activesock_cfg_default(&asock_cfg); 
    2812     asock_cfg.async_cnt = ssock->param.async_cnt; 
    2813     asock_cfg.concurrency = ssock->param.concurrency; 
    2814     asock_cfg.whole_data = PJ_TRUE; 
    2815  
    2816     pj_bzero(&asock_cb, sizeof(asock_cb)); 
    2817     asock_cb.on_accept_complete = asock_on_accept_complete; 
    2818  
    2819     status = pj_activesock_create(pool, 
    2820                                   ssock->sock, 
    2821                                   ssock->param.sock_type, 
    2822                                   &asock_cfg, 
    2823                                   ssock->param.ioqueue, 
    2824                                   &asock_cb, 
    2825                                   ssock, 
    2826                                   &ssock->asock); 
    2827  
    2828     if (status != PJ_SUCCESS) 
    2829         goto on_error; 
    2830  
    2831     /* Start accepting */ 
    2832     pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param); 
    2833     status = pj_activesock_start_accept(ssock->asock, pool); 
    2834     if (status != PJ_SUCCESS) 
    2835         goto on_error; 
    2836  
    2837     /* Update local address */ 
    2838     ssock->addr_len = addr_len; 
    2839     status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, 
    2840                                  &ssock->addr_len); 
    2841     if (status != PJ_SUCCESS) 
    2842         pj_sockaddr_cp(&ssock->local_addr, localaddr); 
    2843  
    2844     ssock->is_server = PJ_TRUE; 
    2845  
    2846     return PJ_SUCCESS; 
    2847  
    2848 on_error: 
    2849     tls_sock_reset(ssock); 
    2850     return status; 
    2851 } 
    2852  
    2853  
    2854 /** 
    2855  * Starts asynchronous socket connect() operation. 
    2856  */ 
    2857 PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock, 
    2858                                                pj_pool_t *pool, 
    2859                                                const pj_sockaddr_t *localaddr, 
    2860                                                const pj_sockaddr_t *remaddr, 
    2861                                                int addr_len) 
    2862 { 
    2863     pj_activesock_cb asock_cb; 
    2864     pj_activesock_cfg asock_cfg; 
    2865     pj_status_t status; 
    2866  
    2867     PJ_ASSERT_RETURN(ssock && pool && localaddr && remaddr && addr_len, 
    2868                      PJ_EINVAL); 
    2869  
    2870     /* Create socket */ 
    2871     status = pj_sock_socket(ssock->param.sock_af, ssock->param.sock_type, 0, 
    2872                             &ssock->sock); 
    2873     if (status != PJ_SUCCESS) 
    2874         goto on_error; 
    2875  
    2876     /* Apply QoS, if specified */ 
    2877     status = pj_sock_apply_qos2(ssock->sock, ssock->param.qos_type, 
    2878                                 &ssock->param.qos_params, 2, 
    2879                                 ssock->pool->obj_name, NULL); 
    2880     if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error) 
    2881         goto on_error; 
    2882  
    2883     /* Bind socket */ 
    2884     status = pj_sock_bind(ssock->sock, localaddr, addr_len); 
    2885     if (status != PJ_SUCCESS) 
    2886         goto on_error; 
    2887  
    2888     /* Create active socket */ 
    2889     pj_activesock_cfg_default(&asock_cfg); 
    2890     asock_cfg.async_cnt = ssock->param.async_cnt; 
    2891     asock_cfg.concurrency = ssock->param.concurrency; 
    2892     asock_cfg.whole_data = PJ_TRUE; 
    2893  
    2894     pj_bzero(&asock_cb, sizeof(asock_cb)); 
    2895     asock_cb.on_connect_complete = asock_on_connect_complete; 
    2896     asock_cb.on_data_read = asock_on_data_read; 
    2897     asock_cb.on_data_sent = asock_on_data_sent; 
    2898  
    2899     status = pj_activesock_create(pool, 
    2900                                   ssock->sock, 
    2901                                   ssock->param.sock_type, 
    2902                                   &asock_cfg, 
    2903                                   ssock->param.ioqueue, 
    2904                                   &asock_cb, 
    2905                                   ssock, 
    2906                                   &ssock->asock); 
    2907  
    2908     if (status != PJ_SUCCESS) 
    2909         goto on_error; 
    2910  
    2911     /* Save remote address */ 
    2912     pj_sockaddr_cp(&ssock->rem_addr, remaddr); 
    2913  
    2914     /* Start timer */ 
    2915     if (ssock->param.timer_heap && 
    2916         (ssock->param.timeout.sec != 0 || ssock->param.timeout.msec != 0)) 
    2917     { 
    2918         pj_assert(ssock->timer.id == TIMER_NONE); 
    2919         ssock->timer.id = TIMER_HANDSHAKE_TIMEOUT; 
    2920         status = pj_timer_heap_schedule(ssock->param.timer_heap, 
    2921                                         &ssock->timer, 
    2922                                         &ssock->param.timeout); 
    2923         if (status != PJ_SUCCESS) 
    2924             ssock->timer.id = TIMER_NONE; 
    2925     } 
    2926  
    2927     status = pj_activesock_start_connect(ssock->asock, pool, remaddr, 
    2928                                          addr_len); 
    2929  
    2930     if (status == PJ_SUCCESS) 
    2931         asock_on_connect_complete(ssock->asock, PJ_SUCCESS); 
    2932     else if (status != PJ_EPENDING) 
    2933         goto on_error; 
    2934  
    2935     /* Update local address */ 
    2936     ssock->addr_len = addr_len; 
    2937     status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, 
    2938                                  &ssock->addr_len); 
    2939     /* Note that we may not get an IP address here. This can 
    2940      * happen for example on Windows, where getsockname() 
    2941      * would return 0.0.0.0 if socket has just started the 
    2942      * async connect. In this case, just leave the local 
    2943      * address with 0.0.0.0 for now; it will be updated 
    2944      * once the socket is established. 
    2945      */ 
    2946  
    2947     /* Update socket state */ 
    2948     ssock->is_server = PJ_FALSE; 
    2949  
    2950     return PJ_EPENDING; 
    2951  
    2952 on_error: 
    2953     tls_sock_reset(ssock); 
    2954     return status; 
    2955 } 
    2956  
    2957  
    2958 PJ_DEF(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock) 
    2959 { 
     1217static pj_status_t ssl_renegotiate(pj_ssl_sock_t *ssock) 
     1218{ 
     1219    gnutls_sock_t *gssock = (gnutls_sock_t *)ssock; 
    29601220    int status; 
    29611221 
    2962     /* Nothing established yet */ 
    2963     PJ_ASSERT_RETURN(ssock->connection_state == TLS_STATE_ESTABLISHED, 
    2964                      PJ_EINVALIDOP); 
    2965  
    2966     /* Cannot renegotiate; we're a client */ 
    2967     /* FIXME: in fact maybe that's not true */ 
    2968     PJ_ASSERT_RETURN(!ssock->is_server, PJ_EINVALIDOP); 
    2969  
    29701222    /* First call gnutls_rehandshake() to see if this is even possible */ 
    2971     status = gnutls_rehandshake(ssock->session); 
     1223    status = gnutls_rehandshake(gssock->session); 
    29721224 
    29731225    if (status == GNUTLS_E_SUCCESS) { 
     
    29801232         *                                      renegotiate 
    29811233         */ 
    2982         ssock->connection_state = TLS_STATE_HANDSHAKING; 
    2983         status = tls_try_handshake(ssock); 
    2984  
    2985         return status; 
     1234        return PJ_SUCCESS; 
    29861235    } else { 
    29871236        return tls_status_from_err(ssock, status); 
Note: See TracChangeset for help on using the changeset viewer.