Changeset 861 for pjproject/trunk


Ignore:
Timestamp:
Dec 25, 2006 6:43:59 AM (18 years ago)
Author:
bennylp
Message:

Major TLS work (ticket #3): asynchronous socket, rather complete TLS options, and pjsua integration. The TLS support should work in both client and server mode.

Location:
pjproject/trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c

    r849 r861  
    139139    puts  ("  --use-stun1=host[:port]"); 
    140140    puts  ("  --use-stun2=host[:port]  Resolve local IP with the specified STUN servers"); 
    141 #if defined(PJSIP_HAS_TLS_TRANSPORT) && PJSIP_HAS_TLS_TRANSPORT!=0 
     141    puts  (""); 
     142    puts  ("TLS Options:"); 
    142143    puts  ("  --use-tls           Enable TLS transport"); 
    143     puts  ("  --tls-ca-file       Specify TLS CA file"); 
    144     puts  ("  --tls-key-file      Specify TLS client key file"); 
    145     puts  ("  --tls-password      Specify TLS password"); 
    146 #endif 
     144    puts  ("  --tls-ca-file       Specify TLS CA file (default=none)"); 
     145    puts  ("  --tls-cert-file     Specify TLS certificate file (default=none)"); 
     146    puts  ("  --tls-privkey-file  Specify TLS private key file (default=none)"); 
     147    puts  ("  --tls-password      Specify TLS password to private key file (default=none)"); 
     148    puts  ("  --tls-verify-server Verify server's certificate (default=no)"); 
     149    puts  ("  --tls-verify-client Verify client's certificate (default=no)"); 
     150    puts  ("  --tls-neg-timeout   Specify TLS negotiation timeout (default=no)"); 
     151 
    147152    puts  (""); 
    148153    puts  ("Media Options:"); 
     
    307312           OPT_DURATION, OPT_NO_TCP, OPT_NO_UDP, OPT_THREAD_CNT, 
    308313           OPT_NOREFERSUB, 
    309            OPT_USE_TLS, OPT_TLS_CA_FILE, OPT_TLS_KEY_FILE, OPT_TLS_PASSWORD, 
     314           OPT_USE_TLS, OPT_TLS_CA_FILE, OPT_TLS_CERT_FILE, OPT_TLS_PRIV_FILE, 
     315           OPT_TLS_PASSWORD, OPT_TLS_VERIFY_SERVER, OPT_TLS_VERIFY_CLIENT, 
     316           OPT_TLS_NEG_TIMEOUT, 
    310317    }; 
    311318    struct pj_getopt_option long_options[] = { 
     
    364371        { "use-tls",    0, 0, OPT_USE_TLS},  
    365372        { "tls-ca-file",1, 0, OPT_TLS_CA_FILE}, 
    366         { "tls-key-file",1,0, OPT_TLS_KEY_FILE},  
     373        { "tls-cert-file",1,0, OPT_TLS_CERT_FILE},  
     374        { "tls-privkey-file",1,0, OPT_TLS_PRIV_FILE}, 
    367375        { "tls-password",1,0, OPT_TLS_PASSWORD}, 
     376        { "tls-verify-server", 0, 0, OPT_TLS_VERIFY_SERVER}, 
     377        { "tls-verify-client", 0, 0, OPT_TLS_VERIFY_CLIENT}, 
     378        { "tls-neg-timeout", 1, 0, OPT_TLS_NEG_TIMEOUT}, 
    368379        { NULL, 0, 0, 0} 
    369380    }; 
     
    789800        case OPT_USE_TLS: 
    790801            cfg->use_tls = PJ_TRUE; 
     802#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
     803            PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
     804            return -1; 
     805#endif 
    791806            break; 
    792807             
    793808        case OPT_TLS_CA_FILE: 
    794             cfg->udp_cfg.tls_ca_file = pj_str(pj_optarg); 
     809            cfg->udp_cfg.tls_setting.ca_list_file = pj_str(pj_optarg); 
     810#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
     811            PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
     812            return -1; 
     813#endif 
    795814            break; 
    796815             
    797         case OPT_TLS_KEY_FILE: 
    798             cfg->udp_cfg.tls_key_file = pj_str(pj_optarg); 
     816        case OPT_TLS_CERT_FILE: 
     817            cfg->udp_cfg.tls_setting.cert_file = pj_str(pj_optarg); 
     818#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
     819            PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
     820            return -1; 
     821#endif 
    799822            break; 
    800823             
     824        case OPT_TLS_PRIV_FILE: 
     825            cfg->udp_cfg.tls_setting.privkey_file = pj_str(pj_optarg); 
     826            break; 
     827 
    801828        case OPT_TLS_PASSWORD: 
    802             cfg->udp_cfg.tls_password = pj_str(pj_optarg); 
     829            cfg->udp_cfg.tls_setting.password = pj_str(pj_optarg); 
     830#if !defined(PJSIP_HAS_TLS_TRANSPORT) || PJSIP_HAS_TLS_TRANSPORT==0 
     831            PJ_LOG(1,(THIS_FILE, "Error: TLS support is not configured")); 
     832            return -1; 
     833#endif 
     834            break; 
     835 
     836        case OPT_TLS_VERIFY_SERVER: 
     837            cfg->udp_cfg.tls_setting.verify_server = PJ_TRUE; 
     838            break; 
     839 
     840        case OPT_TLS_VERIFY_CLIENT: 
     841            cfg->udp_cfg.tls_setting.verify_client = PJ_TRUE; 
     842            break; 
     843 
     844        case OPT_TLS_NEG_TIMEOUT: 
     845            cfg->udp_cfg.tls_setting.timeout.sec = atoi(pj_optarg); 
    803846            break; 
    804847 
     
    10341077    if (config->use_tls) 
    10351078        pj_strcat2(&cfg, "--use-tls\n"); 
    1036     if (config->udp_cfg.tls_ca_file.slen) { 
     1079    if (config->udp_cfg.tls_setting.ca_list_file.slen) { 
    10371080        pj_ansi_sprintf(line, "--tls-ca-file %.*s\n", 
    1038                         (int)config->udp_cfg.tls_ca_file.slen,  
    1039                         config->udp_cfg.tls_ca_file.ptr); 
     1081                        (int)config->udp_cfg.tls_setting.ca_list_file.slen,  
     1082                        config->udp_cfg.tls_setting.ca_list_file.ptr); 
    10401083        pj_strcat2(&cfg, line); 
    10411084    } 
    1042     if (config->udp_cfg.tls_key_file.slen) { 
    1043         pj_ansi_sprintf(line, "--tls-key-file %.*s\n", 
    1044                         (int)config->udp_cfg.tls_key_file.slen,  
    1045                         config->udp_cfg.tls_key_file.ptr); 
     1085    if (config->udp_cfg.tls_setting.cert_file.slen) { 
     1086        pj_ansi_sprintf(line, "--tls-cert-file %.*s\n", 
     1087                        (int)config->udp_cfg.tls_setting.cert_file.slen,  
     1088                        config->udp_cfg.tls_setting.cert_file.ptr); 
    10461089        pj_strcat2(&cfg, line); 
    10471090    } 
    1048     if (config->udp_cfg.tls_password.slen) { 
     1091    if (config->udp_cfg.tls_setting.privkey_file.slen) { 
     1092        pj_ansi_sprintf(line, "--tls-privkey-file %.*s\n", 
     1093                        (int)config->udp_cfg.tls_setting.privkey_file.slen,  
     1094                        config->udp_cfg.tls_setting.privkey_file.ptr); 
     1095        pj_strcat2(&cfg, line); 
     1096    } 
     1097 
     1098    if (config->udp_cfg.tls_setting.password.slen) { 
    10491099        pj_ansi_sprintf(line, "--tls-password %.*s\n", 
    1050                         (int)config->udp_cfg.tls_password.slen,  
    1051                         config->udp_cfg.tls_password.ptr); 
     1100                        (int)config->udp_cfg.tls_setting.password.slen,  
     1101                        config->udp_cfg.tls_setting.password.ptr); 
     1102        pj_strcat2(&cfg, line); 
     1103    } 
     1104 
     1105    if (config->udp_cfg.tls_setting.verify_server) 
     1106        pj_strcat2(&cfg, "--tls-verify-server\n"); 
     1107 
     1108    if (config->udp_cfg.tls_setting.verify_client) 
     1109        pj_strcat2(&cfg, "--tls-verify-client\n"); 
     1110 
     1111    if (config->udp_cfg.tls_setting.timeout.sec) { 
     1112        pj_ansi_sprintf(line, "--tls-neg-timeout %d\n", 
     1113                        config->udp_cfg.tls_setting.timeout.sec); 
    10521114        pj_strcat2(&cfg, line); 
    10531115    } 
     
    28302892    /* Add TLS transport when application wants one */ 
    28312893    if (app_config.use_tls) { 
     2894 
     2895        pjsua_acc_id acc_id; 
     2896 
     2897        /* Set TLS port as TCP port+1 */ 
     2898        app_config.udp_cfg.port++; 
    28322899        status = pjsua_transport_create(PJSIP_TRANSPORT_TLS, 
    28332900                                        &app_config.udp_cfg,  
    28342901                                        &transport_id); 
     2902        app_config.udp_cfg.port--; 
    28352903        if (status != PJ_SUCCESS) 
    28362904            goto on_error; 
     2905         
     2906        /* Add local account */ 
     2907        pjsua_acc_add_local(transport_id, PJ_FALSE, &acc_id); 
     2908        pjsua_acc_set_online_status(acc_id, PJ_TRUE); 
    28372909    } 
    28382910#endif 
  • pjproject/trunk/pjsip/include/pjsip/sip_config.h

    r849 r861  
    201201 
    202202/** 
     203 * The TCP incoming connection backlog number to be set in accept(). 
     204 * 
     205 * Default: 5 
     206 * 
     207 * @see PJSIP_TLS_TRANSPORT_BACKLOG 
     208 */ 
     209#ifndef PJSIP_TCP_TRANSPORT_BACKLOG 
     210#   define PJSIP_TCP_TRANSPORT_BACKLOG  5 
     211#endif 
     212 
     213 
     214/** 
    203215 * This macro specifies whether full DNS resolution should be used. 
    204216 * When enabled, #pjsip_resolve() will perform asynchronous DNS SRV and 
     
    217229 * 
    218230 * Default: 1 (enabled) 
     231 * 
     232 * @see PJSIP_MAX_RESOLVED_ADDRESSES 
    219233 */ 
    220234#ifndef PJSIP_HAS_RESOLVER 
     
    229243 * 
    230244 * Default: 8 
     245 * 
     246 * @see PJSIP_HAS_RESOLVER 
    231247 */ 
    232248#ifndef PJSIP_MAX_RESOLVED_ADDRESSES 
     
    243259#ifndef PJSIP_HAS_TLS_TRANSPORT 
    244260#   define PJSIP_HAS_TLS_TRANSPORT          0 
     261#endif 
     262 
     263 
     264/** 
     265 * The TLS pending incoming connection backlog number to be set in accept(). 
     266 * 
     267 * Default: 5 
     268 * 
     269 * @see PJSIP_TCP_TRANSPORT_BACKLOG 
     270 */ 
     271#ifndef PJSIP_TLS_TRANSPORT_BACKLOG 
     272#   define PJSIP_TLS_TRANSPORT_BACKLOG      5 
    245273#endif 
    246274 
  • pjproject/trunk/pjsip/include/pjsip/sip_errno.h

    r718 r861  
    398398 
    399399 
     400/************************************************************ 
     401 * TLS TRANSPORT ERRORS 
     402 ***********************************************************/ 
     403/** 
     404 * @hideinitializer 
     405 * Unknown TLS error 
     406 */ 
     407#define PJSIP_TLS_EUNKNOWN      (PJSIP_ERRNO_START_PJSIP+160)   /* 171160 */ 
     408/** 
     409 * @hideinitializer 
     410 * Invalid SSL protocol method. 
     411 */ 
     412#define PJSIP_TLS_EINVMETHOD    (PJSIP_ERRNO_START_PJSIP+161)   /* 171161 */ 
     413/** 
     414 * @hideinitializer 
     415 * Error loading/verifying SSL CA list file. 
     416 */ 
     417#define PJSIP_TLS_ECACERT       (PJSIP_ERRNO_START_PJSIP+162)   /* 171162 */ 
     418/** 
     419 * @hideinitializer 
     420 * Error loading SSL certificate chain file. 
     421 */ 
     422#define PJSIP_TLS_ECERTFILE     (PJSIP_ERRNO_START_PJSIP+163)   /* 171163 */ 
     423/** 
     424 * @hideinitializer 
     425 * Error adding private key from SSL certificate file. 
     426 */ 
     427#define PJSIP_TLS_EKEYFILE      (PJSIP_ERRNO_START_PJSIP+164)   /* 171164 */ 
     428/** 
     429 * @hideinitializer 
     430 * Error setting SSL cipher list. 
     431 */ 
     432#define PJSIP_TLS_ECIPHER       (PJSIP_ERRNO_START_PJSIP+165)   /* 171165 */ 
     433/** 
     434 * @hideinitializer 
     435 * Error creating SSL context. 
     436 */ 
     437#define PJSIP_TLS_ECTX          (PJSIP_ERRNO_START_PJSIP+166)   /* 171166 */ 
     438/** 
     439 * @hideinitializer 
     440 * Error creating SSL connection object. 
     441 */ 
     442#define PJSIP_TLS_ESSLCONN      (PJSIP_ERRNO_START_PJSIP+167)   /* 171167 */ 
     443/** 
     444 * @hideinitializer 
     445 * Unknown error when performing SSL connect(). 
     446 */ 
     447#define PJSIP_TLS_ECONNECT      (PJSIP_ERRNO_START_PJSIP+168)   /* 171168 */ 
     448/** 
     449 * @hideinitializer 
     450 * Unknown error when performing SSL accept(). 
     451 */ 
     452#define PJSIP_TLS_EACCEPT       (PJSIP_ERRNO_START_PJSIP+169)   /* 171169 */ 
     453/** 
     454 * @hideinitializer 
     455 * Unknown error when sending SSL data 
     456 */ 
     457#define PJSIP_TLS_ESEND         (PJSIP_ERRNO_START_PJSIP+170)   /* 171170 */ 
     458/** 
     459 * @hideinitializer 
     460 * Unknown error when reading SSL data 
     461 */ 
     462#define PJSIP_TLS_EREAD         (PJSIP_ERRNO_START_PJSIP+171)   /* 171171 */ 
     463/** 
     464 * @hideinitializer 
     465 * SSL negotiation has exceeded the maximum configured timeout. 
     466 */ 
     467#define PJSIP_TLS_ETIMEDOUT     (PJSIP_ERRNO_START_PJSIP+172)   /* 171172 */ 
     468 
     469 
    400470 
    401471 
  • pjproject/trunk/pjsip/include/pjsip/sip_transport_tcp.h

    r742 r861  
    3737 * the transport to the framework. 
    3838 */ 
    39  
    40 /** 
    41  * The TCP incoming connection backlog number. 
    42  * Default: 5 
    43  */ 
    44 #ifndef PJSIP_TCP_TRANSPORT_BACKLOG 
    45 #   define PJSIP_TCP_TRANSPORT_BACKLOG  5 
    46 #endif 
    47  
    4839 
    4940/** 
  • pjproject/trunk/pjsip/include/pjsip/sip_transport_tls.h

    r849 r861  
    2626 
    2727#include <pjsip/sip_transport.h> 
     28#include <pj/string.h> 
     29 
    2830 
    2931PJ_BEGIN_DECL 
     
    3840 */ 
    3941 
     42/** SSL protocol method constants. */ 
     43typedef enum pjsip_ssl_method 
     44{ 
     45    PJSIP_SSL_DEFAULT_METHOD    = 0,    /**< Default protocol method.   */ 
     46    PJSIP_TLSV1_METHOD          = 1,    /**< Use SSLv1 method.          */ 
     47    PJSIP_SSLV2_METHOD          = 2,    /**< Use SSLv2 method.          */ 
     48    PJSIP_SSLV3_METHOD          = 3,    /**< Use SSLv3 method.          */ 
     49    PJSIP_SSLV23_METHOD         = 23    /**< Use SSLv23 method.         */ 
     50} pjsip_ssl_method; 
     51 
     52 
     53/** 
     54 * TLS transport settings. 
     55 */ 
     56typedef struct pjsip_tls_setting 
     57{ 
     58    /** 
     59     * Certificate of Authority (CA) list file. 
     60     */ 
     61    pj_str_t    ca_list_file; 
     62 
     63    /** 
     64     * Public endpoint certificate file, which will be used as client- 
     65     * side  certificate for outgoing TLS connection, and server-side 
     66     * certificate for incoming TLS connection. 
     67     */ 
     68    pj_str_t    cert_file; 
     69 
     70    /** 
     71     * Optional private key of the endpoint certificate to be used. 
     72     */ 
     73    pj_str_t    privkey_file; 
     74 
     75    /** 
     76     * Password to open private key. 
     77     */ 
     78    pj_str_t    password; 
     79 
     80    /** 
     81     * TLS protocol method from #pjsip_ssl_method, which can be: 
     82     *  - PJSIP_SSL_DEFAULT_METHOD(0):  default (which will use SSLv23) 
     83     *  - PJSIP_TLSV1_METHOD(1):        TLSv1 
     84     *  - PJSIP_SSLV2_METHOD(2):        TLSv2 
     85     *  - PJSIP_SSLV3_METHOD(3):        TLSv3 
     86     *  - PJSIP_SSLV23_METHOD(23):      TLSv23 
     87     * 
     88     * Default is PJSIP_SSL_DEFAULT_METHOD (0), which will use SSLv23 
     89     * protocol method. 
     90     */ 
     91    int         method; 
     92 
     93    /** 
     94     * TLS cipher list string in OpenSSL format. If empty, then default 
     95     * cipher list of the backend will be used. 
     96     */ 
     97    pj_str_t    ciphers; 
     98 
     99    /** 
     100     * When PJSIP is acting as a client (outgoing TLS connections),  
     101     * it will always receive a certificate from the peer.  
     102     * If \a verify_server is disabled (set to zero), PJSIP will not  
     103     * verifiy the certificate and allows TLS connections to servers  
     104     * which do not present a valid certificate.  
     105     * If \a tls_verify_server is non-zero, PJSIP verifies the server  
     106     * certificate and will close the TLS connection if the server  
     107     * certificate is not valid. 
     108     * 
     109     * This setting corresponds to OpenSSL SSL_VERIFY_PEER flag. 
     110     * Default value is zero. 
     111     */ 
     112    pj_bool_t   verify_server; 
     113 
     114    /** 
     115     * When acting as server (incoming TLS connections), setting 
     116     * \a verify_client to non-zero will cause the transport to activate 
     117     * peer verification upon receiving incoming TLS connection. 
     118     * 
     119     * This setting corresponds to OpenSSL SSL_VERIFY_PEER flag. 
     120     * Default value is zero. 
     121     */ 
     122    pj_bool_t   verify_client; 
     123 
     124    /** 
     125     * When acting as server (incoming TLS connections), reject inocming 
     126     * connection if client doesn't have a valid certificate. 
     127     * 
     128     * This setting corresponds to SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag. 
     129     * Default value is zero. 
     130     */ 
     131    pj_bool_t   require_client_cert; 
     132 
     133    /** 
     134     * TLS negotiation timeout to be applied for both outgoing and 
     135     * incoming connection. If both sec and msec member is set to zero, 
     136     * the SSL negotiation doesn't have a timeout. 
     137     */ 
     138    pj_time_val timeout; 
     139 
     140} pjsip_tls_setting; 
     141 
     142 
     143/** 
     144 * Initialize TLS setting with default values. 
     145 * 
     146 * @param tls_opt   The TLS setting to be initialized. 
     147 */ 
     148PJ_INLINE(void) pjsip_tls_setting_default(pjsip_tls_setting *tls_opt) 
     149{ 
     150    pj_memset(tls_opt, 0, sizeof(*tls_opt)); 
     151} 
     152 
     153 
     154/** 
     155 * Copy TLS setting. 
     156 * 
     157 * @param pool      The pool to duplicate strings etc. 
     158 * @param dst       Destination structure. 
     159 * @param src       Source structure. 
     160 */ 
     161PJ_INLINE(void) pjsip_tls_setting_copy(pj_pool_t *pool, 
     162                                       pjsip_tls_setting *dst, 
     163                                       const pjsip_tls_setting *src) 
     164{ 
     165    pj_memcpy(dst, src, sizeof(*dst)); 
     166    pj_strdup_with_null(pool, &dst->ca_list_file, &src->ca_list_file); 
     167    pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file); 
     168    pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file); 
     169    pj_strdup_with_null(pool, &dst->password, &src->password); 
     170    pj_strdup_with_null(pool, &dst->ciphers, &src->ciphers); 
     171} 
     172 
     173 
    40174/** 
    41175 * Register support for SIP TLS transport by creating TLS listener on 
     
    45179 * 
    46180 * @param endpt         The SIP endpoint. 
    47  * @param keyfile       Path to keys and certificate file. 
    48  * @param password      Password to open the private key. 
    49  * @param ca_list_file  Path to Certificate of Authority file. 
     181 * @param opt           Optional TLS settings. 
    50182 * @param local         Optional local address to bind, or specify the 
    51183 *                      address to bind the server socket to. Both IP  
     
    72204 */ 
    73205PJ_DECL(pj_status_t) pjsip_tls_transport_start(pjsip_endpoint *endpt, 
    74                                                const pj_str_t *keyfile, 
    75                                                const pj_str_t *password, 
    76                                                const pj_str_t *ca_list_file, 
     206                                               const pjsip_tls_setting *opt, 
    77207                                               const pj_sockaddr_in *local, 
    78208                                               const pjsip_host_port *a_name, 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r849 r861  
    842842 
    843843    /** 
    844      * TLS root CA file path (only used for TLS transport). 
    845      */ 
    846     pj_str_t            tls_ca_file; 
    847  
    848     /** 
    849      * TLS client key path (only used for TLS transport). 
    850      */ 
    851     pj_str_t            tls_key_file; 
    852  
    853     /** 
    854      * TLS password (only used for TLS transport). 
    855      */ 
    856     pj_str_t            tls_password; 
     844     * TLS settings. 
     845     */ 
     846    pjsip_tls_setting   tls_setting; 
    857847 
    858848} pjsua_transport_config; 
     
    867857{ 
    868858    pj_bzero(cfg, sizeof(*cfg)); 
     859    pjsip_tls_setting_default(&cfg->tls_setting); 
    869860} 
    870861 
  • pjproject/trunk/pjsip/src/pjsip/sip_errno.c

    r534 r861  
    109109    PJ_BUILD_ERR( PJSIP_ESESSIONTERMINATED, "INVITE session already terminated" ), 
    110110    PJ_BUILD_ERR( PJSIP_ESESSIONSTATE,      "Invalid INVITE session state" ), 
     111 
     112    /* SSL errors */ 
     113    PJ_BUILD_ERR( PJSIP_TLS_EUNKNOWN,   "Unknown TLS error" ), 
     114    PJ_BUILD_ERR( PJSIP_TLS_EINVMETHOD, "Invalid SSL protocol method" ), 
     115    PJ_BUILD_ERR( PJSIP_TLS_ECACERT,    "Error loading/verifying SSL CA list file"), 
     116    PJ_BUILD_ERR( PJSIP_TLS_ECERTFILE,  "Error loading SSL certificate chain file"), 
     117    PJ_BUILD_ERR( PJSIP_TLS_EKEYFILE,   "Error adding private key from SSL certificate file"), 
     118    PJ_BUILD_ERR( PJSIP_TLS_ECIPHER,    "Error setting SSL cipher list"), 
     119    PJ_BUILD_ERR( PJSIP_TLS_ECTX,       "Error creating SSL context"), 
     120    PJ_BUILD_ERR( PJSIP_TLS_ESSLCONN,   "Error creating SSL connection object"), 
     121    PJ_BUILD_ERR( PJSIP_TLS_ECONNECT,   "Unknown error when performing SSL connect()"), 
     122    PJ_BUILD_ERR( PJSIP_TLS_EACCEPT,    "Unknown error when performing SSL accept()"), 
     123    PJ_BUILD_ERR( PJSIP_TLS_ESEND,      "Unknown error when sending SSL data"), 
     124    PJ_BUILD_ERR( PJSIP_TLS_EREAD,      "Unknown error when reading SSL data"), 
     125    PJ_BUILD_ERR( PJSIP_TLS_ETIMEDOUT,  "SSL negotiation has timed out"), 
    111126}; 
    112127 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport.c

    r792 r861  
    12901290    pj_hash_iterator_t itr_val; 
    12911291    pj_hash_iterator_t *itr; 
     1292    pjsip_tpfactory *factory; 
    12921293 
    12931294    pj_lock_acquire(mgr->lock); 
     
    12981299#endif 
    12991300 
     1301    PJ_LOG(3, (THIS_FILE, " Dumping listeners:")); 
     1302    factory = mgr->factory_list.next; 
     1303    while (factory != &mgr->factory_list) { 
     1304        PJ_LOG(3, (THIS_FILE, "  %s %s:%.*s:%d",  
     1305                   factory->obj_name, 
     1306                   factory->type_name, 
     1307                   (int)factory->addr_name.host.slen, 
     1308                   factory->addr_name.host.ptr, 
     1309                   (int)factory->addr_name.port)); 
     1310        factory = factory->next; 
     1311    } 
     1312 
    13001313    itr = pj_hash_first(mgr->table, &itr_val); 
    13011314    if (itr) { 
     
    13051318            pjsip_transport *t = pj_hash_this(mgr->table, itr); 
    13061319 
    1307             PJ_LOG(3, (THIS_FILE, "  %s %s (refcnt=%d)",  
     1320            PJ_LOG(3, (THIS_FILE, "  %s %s (refcnt=%d%s)",  
    13081321                       t->obj_name, 
    13091322                       t->info, 
    1310                        pj_atomic_get(t->ref_cnt))); 
     1323                       pj_atomic_get(t->ref_cnt), 
     1324                       (t->idle_timer.id ? " [idle]" : ""))); 
    13111325 
    13121326            itr = pj_hash_next(mgr->table, itr); 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport_tls_ossl.c

    r858 r861  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
    1818 */ 
    19 #include <pjsip/sip_transport.h> 
     19#include <pjsip/sip_transport_tls.h> 
    2020#include <pjsip/sip_endpoint.h> 
    2121#include <pjsip/sip_errno.h> 
     22#include <pj/compat/socket.h> 
    2223#include <pj/addr_resolv.h> 
    2324#include <pj/assert.h> 
     25#include <pj/ioqueue.h> 
    2426#include <pj/lock.h> 
    2527#include <pj/log.h> 
    2628#include <pj/os.h> 
    2729#include <pj/pool.h> 
     30#include <pj/compat/socket.h> 
    2831#include <pj/sock_select.h> 
    2932#include <pj/string.h> 
    30 #include <pj/compat/socket.h> 
    3133 
    3234 
     
    3537 
    3638 
    37 /* OpenSSL headers */ 
    38  
     39 
     40/*  
     41 * Include OpenSSL headers  
     42 */ 
    3943#include <openssl/bio.h> 
    4044#include <openssl/ssl.h> 
    4145#include <openssl/err.h> 
    4246 
     47/* 
     48 * With VisualC++, it's not possible to dynamically link against some 
     49 * libraries when some macros are defined (unlike "make" based build 
     50 * system where this can be easily manipulated). 
     51 * 
     52 * So for VisualC++ IDE, include OpenSSL libraries in the linking by 
     53 * using the #pragma lib construct below. 
     54 */ 
    4355#ifdef _MSC_VER 
    4456# ifdef _DEBUG 
     
    5163#endif 
    5264 
     65 
     66#define THIS_FILE       "transport_tls_ossl.c" 
     67 
     68#define MAX_ASYNC_CNT   16 
     69#define POOL_LIS_INIT   4000 
     70#define POOL_LIS_INC    4001 
     71#define POOL_TP_INIT    4000 
     72#define POOL_TP_INC     4002 
     73 
     74 
     75 
    5376/** 
    54  * @hideinitializer 
    55  * Unable to read SSL certificate file. 
    56  */ 
    57 #define PJSIP_TLS_ECERTFILE     PJ_EUNKNOWN 
    58 /** 
    59  * @hideinitializer 
    60  * Unable to read SSL private key file. 
    61  */ 
    62 #define PJSIP_TLS_EKEYFILE      PJ_EUNKNOWN 
    63 /** 
    64  * @hideinitializer 
    65  * Error creating SSL context. 
    66  */ 
    67 #define PJSIP_TLS_ECTX          PJ_EUNKNOWN 
    68 /** 
    69  * @hideinitializer 
    70  * Unable to list SSL CA list. 
    71  */ 
    72 #define PJSIP_TLS_ECALIST       PJ_EUNKNOWN 
    73 /** 
    74  * @hideinitializer 
    75  * SSL connect() error 
    76  */ 
    77 #define PJSIP_TLS_ECONNECT      PJ_EUNKNOWN 
    78 /** 
    79  * @hideinitializer 
    80  * Error sending SSL data 
    81  */ 
    82 #define PJSIP_TLS_ESEND         PJ_EUNKNOWN 
    83  
    84  
    85 #define THIS_FILE       "tls_ssl" 
     77 * Get the number of descriptors in the set. This is defined in sock_select.c 
     78 * This function will only return the number of sockets set from PJ_FD_SET 
     79 * operation. When the set is modified by other means (such as by select()), 
     80 * the count will not be reflected here. 
     81 * 
     82 * That's why don't export this function in the header file, to avoid 
     83 * misunderstanding. 
     84 * 
     85 * @param fdsetp    The descriptor set. 
     86 * 
     87 * @return          Number of descriptors in the set. 
     88 */ 
     89PJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp); 
     90 
     91 
     92 
     93struct tls_listener; 
     94struct tls_transport; 
    8695 
    8796 
    8897/* 
    89  * TLS transport factory/listener. 
     98 * This structure is "descendant" of pj_ioqueue_op_key_t, and it is used to 
     99 * track pending/asynchronous accept() operation. TLS transport may have 
     100 * more than one pending accept() operations, depending on the value of 
     101 * async_cnt. 
     102 */ 
     103struct pending_accept 
     104{ 
     105    pj_ioqueue_op_key_t      op_key; 
     106    struct tls_listener     *listener; 
     107    unsigned                 index; 
     108    pj_pool_t               *pool; 
     109    pj_sock_t                new_sock; 
     110    int                      addr_len; 
     111    pj_sockaddr_in           local_addr; 
     112    pj_sockaddr_in           remote_addr; 
     113}; 
     114 
     115 
     116/* 
     117 * This is the TLS listener, which is a "descendant" of pjsip_tpfactory (the 
     118 * SIP transport factory). 
    90119 */ 
    91120struct tls_listener 
    92121{ 
    93     pjsip_tpfactory  base; 
    94     pjsip_endpoint  *endpt; 
    95     pjsip_tpmgr     *tpmgr; 
    96  
    97     pj_bool_t        is_registered; 
    98  
    99     SSL_CTX         *ctx; 
    100     pj_str_t         password; 
     122    pjsip_tpfactory          factory; 
     123    pj_bool_t                is_registered; 
     124    pjsip_tls_setting        setting; 
     125    pjsip_endpoint          *endpt; 
     126    pjsip_tpmgr             *tpmgr; 
     127    pj_sock_t                sock; 
     128    pj_ioqueue_key_t        *key; 
     129    unsigned                 async_cnt; 
     130    struct pending_accept   *accept_op[MAX_ASYNC_CNT]; 
     131 
     132    SSL_CTX                 *ctx; 
    101133}; 
    102134 
    103135 
    104136/* 
    105  * TLS transport. 
     137 * This structure is used to keep delayed transmit operation in a list. 
     138 * A delayed transmission occurs when application sends tx_data when 
     139 * the TLS connect/establishment is still in progress. These delayed 
     140 * transmission will be "flushed" once the socket is connected (either 
     141 * successfully or with errors). 
     142 */ 
     143struct delayed_tdata 
     144{ 
     145    PJ_DECL_LIST_MEMBER(struct delayed_tdata); 
     146    pjsip_tx_data_op_key    *tdata_op_key; 
     147}; 
     148 
     149 
     150/* 
     151 * This structure describes the TLS transport, and it's descendant of 
     152 * pjsip_transport. 
    106153 */ 
    107154struct tls_transport 
    108155{ 
    109     pjsip_transport  base; 
    110  
    111     pj_sock_t        sock; 
    112     SSL             *ssl; 
    113  
    114     pjsip_rx_data    rdata; 
    115     pj_bool_t        quitting; 
    116     pj_thread_t     *thread; 
     156    pjsip_transport          base; 
     157    pj_bool_t                is_server; 
     158    struct tls_listener     *listener; 
     159    pj_bool_t                is_registered; 
     160    pj_bool_t                is_closing; 
     161    pj_status_t              close_reason; 
     162    pj_sock_t                sock; 
     163    pj_ioqueue_key_t        *key; 
     164    pj_bool_t                has_pending_connect; 
     165 
     166    /* SSL connection */ 
     167    SSL                     *ssl; 
     168    pj_bool_t                ssl_shutdown_called; 
     169 
     170    /* TLS transport can only have  one rdata! 
     171     * Otherwise chunks of incoming PDU may be received on different 
     172     * buffer. 
     173     */ 
     174    pjsip_rx_data            rdata; 
     175 
     176    /* Pending transmission list. */ 
     177    struct delayed_tdata     delayed_list; 
    117178}; 
    118179 
    119180 
    120 /* 
    121  * TLS factory callbacks. 
    122  */ 
     181/**************************************************************************** 
     182 * PROTOTYPES 
     183 */ 
     184 
     185/* This callback is called when pending accept() operation completes. */ 
     186static void on_accept_complete( pj_ioqueue_key_t *key,  
     187                                pj_ioqueue_op_key_t *op_key,  
     188                                pj_sock_t sock,  
     189                                pj_status_t status); 
     190 
     191/* This callback is called by transport manager to destroy listener */ 
     192static pj_status_t lis_destroy(pjsip_tpfactory *factory); 
     193 
     194/* This callback is called by transport manager to create transport */ 
    123195static pj_status_t lis_create_transport(pjsip_tpfactory *factory, 
    124196                                        pjsip_tpmgr *mgr, 
     
    127199                                        int addr_len, 
    128200                                        pjsip_transport **transport); 
    129 static pj_status_t lis_destroy(pjsip_tpfactory *factory); 
    130  
    131  
    132 /* 
    133  * TLS transport callback. 
    134  */ 
    135 static pj_status_t tls_tp_send_msg(pjsip_transport *transport,  
    136                                    pjsip_tx_data *tdata, 
    137                                    const pj_sockaddr_t *rem_addr, 
    138                                    int addr_len, 
    139                                    void *token, 
    140                                    void (*callback)(pjsip_transport *transport, 
    141                                                     void *token,  
    142                                                     pj_ssize_t sent_bytes)); 
    143 static pj_status_t tls_tp_do_shutdown(pjsip_transport *transport); 
    144 static pj_status_t tls_tp_destroy(pjsip_transport *transport); 
    145  
    146  
    147  
    148  
    149 /* 
    150  * Static vars. 
    151  */ 
    152 static int tls_init_count; 
     201 
     202/* Common function to create and initialize transport */ 
     203static pj_status_t tls_create(struct tls_listener *listener, 
     204                              pj_pool_t *pool, 
     205                              pj_sock_t sock, pj_bool_t is_server, 
     206                              const pj_sockaddr_in *local, 
     207                              const pj_sockaddr_in *remote, 
     208                              struct tls_transport **p_tls); 
     209 
     210 
     211/**************************************************************************** 
     212 * SSL FUNCTIONS 
     213 */ 
    153214 
    154215/* ssl_report_error() */ 
    155 static void ssl_report_error(int level, const char *sender,  
     216static void ssl_report_error(const char *sender, int level,  
     217                             pj_status_t status, 
    156218                             const char *format, ...) 
    157219{ 
    158     va_list arg; 
    159     unsigned long ssl_err; 
    160  
    161     va_start(arg, format); 
    162     ssl_err = ERR_get_error(); 
    163  
    164     if (ssl_err == 0) { 
    165         pj_log(sender, level, format, arg); 
    166     } else { 
    167         char err_format[512]; 
     220    va_list marker; 
     221 
     222    va_start(marker, format); 
     223 
     224    if (status != PJ_SUCCESS) { 
     225        char err_format[PJ_ERR_MSG_SIZE + 512]; 
    168226        int len; 
    169227 
    170228        len = pj_ansi_snprintf(err_format, sizeof(err_format), 
    171229                               "%s: ", format); 
    172         ERR_error_string(ssl_err, err_format+len); 
     230        pj_strerror(status, err_format+len, sizeof(err_format)-len); 
    173231         
    174         pj_log(sender, level, err_format, arg); 
    175     } 
    176  
    177     va_end(arg); 
    178 } 
    179  
     232        pj_log(sender, level, err_format, marker); 
     233 
     234    } else { 
     235        unsigned long ssl_err; 
     236 
     237        ssl_err = ERR_get_error(); 
     238 
     239        if (ssl_err == 0) { 
     240            pj_log(sender, level, format, marker); 
     241        } else { 
     242            char err_format[512]; 
     243            int len; 
     244 
     245            len = pj_ansi_snprintf(err_format, sizeof(err_format), 
     246                                   "%s: ", format); 
     247            ERR_error_string(ssl_err, err_format+len); 
     248             
     249            pj_log(sender, level, err_format, marker); 
     250        } 
     251    } 
     252 
     253    va_end(marker); 
     254} 
     255 
     256 
     257static void sockaddr_to_host_port( pj_pool_t *pool, 
     258                                   pjsip_host_port *host_port, 
     259                                   const pj_sockaddr_in *addr ) 
     260{ 
     261    enum { M = 48 }; 
     262    host_port->host.ptr = pj_pool_alloc(pool, M); 
     263    host_port->host.slen = pj_ansi_snprintf( host_port->host.ptr, M, "%s",  
     264                                            pj_inet_ntoa(addr->sin_addr)); 
     265    host_port->port = pj_ntohs(addr->sin_port); 
     266} 
     267 
     268 
     269/* SSL password callback. */ 
     270static int password_cb(char *buf, int num, int rwflag, void *user_data) 
     271{ 
     272    struct tls_listener *lis = user_data; 
     273 
     274    PJ_UNUSED_ARG(rwflag); 
     275 
     276    if(num < lis->setting.password.slen+1) 
     277        return 0; 
     278     
     279    pj_memcpy(buf, lis->setting.password.ptr, lis->setting.password.slen); 
     280    return lis->setting.password.slen; 
     281} 
     282 
     283 
     284/* OpenSSL library initialization counter */ 
     285static int openssl_init_count; 
    180286 
    181287/* Initialize OpenSSL */ 
    182288static pj_status_t init_openssl(void) 
    183289{ 
    184     if (++tls_init_count != 1) 
     290    if (++openssl_init_count != 1) 
    185291        return PJ_SUCCESS; 
    186292 
    187293    SSL_library_init(); 
    188294    SSL_load_error_strings(); 
    189  
    190     ERR_load_BIO_strings(); 
    191295    OpenSSL_add_all_algorithms(); 
    192296 
     
    197301static void shutdown_openssl(void) 
    198302{ 
    199     if (--tls_init_count != 0) 
     303    if (--openssl_init_count != 0) 
    200304        return; 
    201305} 
    202306 
    203 /* SSL password callback. */ 
    204 static int password_cb(char *buf, int num, int rwflag, void *user_data) 
    205 { 
    206     struct tls_listener *lis = user_data; 
    207  
    208     PJ_UNUSED_ARG(rwflag); 
    209  
    210     if(num < lis->password.slen+1) 
    211         return 0; 
    212      
    213     pj_memcpy(buf, lis->password.ptr, lis->password.slen); 
    214     return lis->password.slen; 
    215 } 
    216  
    217307 
    218308/* Create and initialize new SSL context */ 
    219 static pj_status_t initialize_ctx(struct tls_listener *lis, 
    220                                   const char *keyfile,  
    221                                   const char *ca_list_file, 
    222                                   SSL_CTX **p_ctx) 
    223 { 
    224     SSL_METHOD *meth; 
     309static pj_status_t create_ctx( struct tls_listener *lis, SSL_CTX **p_ctx) 
     310{ 
     311    struct pjsip_tls_setting *opt = &lis->setting; 
     312    char *lis_name = lis->factory.obj_name; 
     313    SSL_METHOD *ssl_method; 
    225314    SSL_CTX *ctx; 
     315    int mode, rc; 
    226316         
    227317    *p_ctx = NULL; 
    228318 
    229     /* Create SSL context*/ 
    230     meth = SSLv23_method(); 
    231     ctx = SSL_CTX_new(meth); 
    232     if (ctx == NULL) 
     319    /* Make sure OpenSSL library has been initialized */ 
     320    init_openssl(); 
     321 
     322    /* Determine SSL method to use */ 
     323    switch (opt->method) { 
     324    case PJSIP_SSL_DEFAULT_METHOD: 
     325    case PJSIP_SSLV23_METHOD: 
     326        ssl_method = SSLv23_method(); 
     327        break; 
     328    case PJSIP_TLSV1_METHOD: 
     329        ssl_method = TLSv1_method(); 
     330        break; 
     331    case PJSIP_SSLV2_METHOD: 
     332        ssl_method = SSLv2_method(); 
     333        break; 
     334    case PJSIP_SSLV3_METHOD: 
     335        ssl_method = SSLv3_method(); 
     336        break; 
     337    default: 
     338        ssl_report_error(lis_name, 4, PJSIP_TLS_EINVMETHOD, 
     339                         "Error creating SSL context"); 
     340        return PJSIP_TLS_EINVMETHOD; 
     341    } 
     342 
     343    /* Create SSL context for the listener */ 
     344    ctx = SSL_CTX_new(ssl_method); 
     345    if (ctx == NULL) { 
     346        ssl_report_error(lis_name, 4, PJ_SUCCESS, 
     347                         "Error creating SSL context"); 
    233348        return PJSIP_TLS_ECTX; 
    234  
    235     /* Load the CAs we trust*/ 
    236     if (ca_list_file && *ca_list_file) { 
    237         if(!(SSL_CTX_load_verify_locations(ctx, ca_list_file, 0))) { 
    238             ssl_report_error(2, lis->base.obj_name,  
    239                              "Error loading/verifying CA list file '%s'", 
    240                              ca_list_file); 
     349    } 
     350 
     351 
     352    /* Load CA list if one is specified. */ 
     353    if (opt->ca_list_file.slen) { 
     354 
     355        /* Can only take a NULL terminated filename in the setting */ 
     356        pj_assert(opt->ca_list_file.ptr[opt->ca_list_file.slen] == '\0'); 
     357 
     358        rc = SSL_CTX_load_verify_locations(ctx, opt->ca_list_file.ptr, NULL); 
     359 
     360        if (rc != 1) { 
     361            ssl_report_error(lis_name, 4, PJ_SUCCESS, 
     362                             "Error loading/verifying CA list file '%.*s'", 
     363                             (int)opt->ca_list_file.slen, 
     364                             opt->ca_list_file.ptr); 
    241365            SSL_CTX_free(ctx); 
    242             return PJSIP_TLS_ECALIST; 
    243         } 
    244     } 
    245  
     366            return PJSIP_TLS_ECACERT; 
     367        } 
     368 
     369        PJ_LOG(5,(lis_name, "TLS CA file successfully loaded from '%.*s'", 
     370                  (int)opt->ca_list_file.slen, 
     371                  opt->ca_list_file.ptr)); 
     372    } 
    246373     
    247     /* Load our keys and certificates */ 
    248     if (keyfile && *keyfile) { 
    249         if(!(SSL_CTX_use_certificate_chain_file(ctx, keyfile))) { 
    250             ssl_report_error(2, lis->base.obj_name,  
    251                              "Error loading keys and certificate file '%s'", 
    252                              keyfile); 
     374    /* Set password callback */ 
     375    SSL_CTX_set_default_passwd_cb(ctx, password_cb); 
     376    SSL_CTX_set_default_passwd_cb_userdata(ctx, lis); 
     377 
     378 
     379    /* Load certificate if one is specified */ 
     380    if (opt->cert_file.slen) { 
     381 
     382        /* Can only take a NULL terminated filename in the setting */ 
     383        pj_assert(opt->cert_file.ptr[opt->cert_file.slen] == '\0'); 
     384 
     385        /* Load certificate chain from file into ctx */ 
     386        rc = SSL_CTX_use_certificate_chain_file(ctx, opt->cert_file.ptr); 
     387 
     388        if(rc != 1) { 
     389            ssl_report_error(lis_name, 4, PJ_SUCCESS, 
     390                             "Error loading certificate chain file '%.*s'", 
     391                             (int)opt->cert_file.slen, 
     392                             opt->cert_file.ptr); 
     393            SSL_CTX_free(ctx); 
     394            return PJSIP_TLS_ECERTFILE; 
     395        } 
     396 
     397        PJ_LOG(5,(lis_name, "TLS certificate successfully loaded from '%.*s'", 
     398                  (int)opt->cert_file.slen, 
     399                  opt->cert_file.ptr)); 
     400    } 
     401 
     402 
     403    /* Load private key if one is specified */ 
     404    if (opt->privkey_file.slen) { 
     405 
     406        /* Can only take a NULL terminated filename in the setting */ 
     407        pj_assert(opt->privkey_file.ptr[opt->privkey_file.slen] == '\0'); 
     408 
     409        /* Adds the first private key found in file to ctx */ 
     410        rc = SSL_CTX_use_PrivateKey_file(ctx, opt->privkey_file.ptr,  
     411                                         SSL_FILETYPE_PEM); 
     412 
     413        if(rc != 1) { 
     414            ssl_report_error(lis_name, 4, PJ_SUCCESS, 
     415                             "Error adding private key from '%.*s'", 
     416                             (int)opt->privkey_file.slen, 
     417                             opt->privkey_file.ptr); 
    253418            SSL_CTX_free(ctx); 
    254419            return PJSIP_TLS_EKEYFILE; 
    255420        } 
    256421 
    257         /* Set password callback */ 
    258         SSL_CTX_set_default_passwd_cb(ctx, password_cb); 
    259         SSL_CTX_set_default_passwd_cb_userdata(ctx, lis); 
    260  
    261         if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM))) { 
    262             ssl_report_error(2, lis->base.obj_name,  
    263                              "Error loading private key file '%s'", 
    264                              keyfile); 
     422        PJ_LOG(5,(lis_name, "TLS private key successfully loaded from '%.*s'", 
     423                  (int)opt->privkey_file.slen, 
     424                  opt->privkey_file.ptr)); 
     425    } 
     426 
     427 
     428    /* SSL verification options */ 
     429    if (lis->setting.verify_client || lis->setting.verify_server) { 
     430        mode = SSL_VERIFY_PEER; 
     431        if (lis->setting.require_client_cert) 
     432            mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 
     433    } else { 
     434        mode = SSL_VERIFY_NONE; 
     435    } 
     436 
     437    SSL_CTX_set_verify(ctx, mode, NULL); 
     438 
     439    PJ_LOG(5,(lis_name, "TLS verification mode set to %d", mode)); 
     440 
     441    /* Optionally set cipher list if one is specified */ 
     442    if (opt->ciphers.slen) { 
     443        /* Can only take a NULL terminated cipher list in the setting */ 
     444        pj_assert(opt->cert_file.ptr[opt->cert_file.slen] == '\0'); 
     445 
     446        rc = SSL_CTX_set_cipher_list(ctx, opt->ciphers.ptr); 
     447        if (rc != 1) { 
     448            ssl_report_error(lis_name, 4, PJ_SUCCESS, 
     449                             "Error setting cipher list '%.*s'", 
     450                             (int)opt->ciphers.slen, 
     451                             opt->ciphers.ptr); 
    265452            SSL_CTX_free(ctx); 
    266             return PJSIP_TLS_EKEYFILE; 
    267         } 
    268     } 
    269  
    270 #if (OPENSSL_VERSION_NUMBER < 0x00905100L) 
    271     SSL_CTX_set_verify_depth(ctx,1); 
    272 #endif 
    273      
     453            return PJSIP_TLS_ECIPHER; 
     454        } 
     455 
     456        PJ_LOG(5,(lis_name, "TLS ciphers set to '%.*s'", 
     457                  (int)opt->ciphers.slen, 
     458                  opt->ciphers.ptr)); 
     459    } 
     460 
     461    /* Done! */ 
     462 
    274463    *p_ctx = ctx; 
    275464    return PJ_SUCCESS; 
     
    280469{ 
    281470    SSL_CTX_free(ctx); 
    282 } 
    283  
    284  
    285 /* Check that the common name matches the host name*/ 
    286 #if 0 
    287 static void check_cert(SSL *ssl, char *host) 
    288 { 
    289     X509 *peer; 
    290     char peer_CN[256]; 
    291      
    292     if(SSL_get_verify_result(ssl)!=X509_V_OK) 
    293         berr_exit("Certificate doesn't verify"); 
    294      
    295     /* Check the cert chain. The chain length is automatically checked  
    296      * by OpenSSL when we set the verify depth in the ctx  
     471 
     472    /* Potentially shutdown OpenSSL library if this is the last 
     473     * context exists. 
    297474     */ 
    298      
    299     /* Check the common name */ 
    300     peer = SSL_get_peer_certificate(ssl); 
    301     X509_NAME_get_text_by_NID( X509_get_subject_name(peer), 
    302                                NID_commonName, peer_CN, 256); 
    303  
    304     if(strcasecmp(peer_CN,host)) { 
    305         err_exit("Common name doesn't match host name"); 
    306     } 
    307 } 
    308 #endif 
    309  
    310  
    311  
    312 /* 
    313  * Public function to create TLS listener. 
    314  */ 
    315 PJ_DEF(pj_status_t) pjsip_tls_transport_start(pjsip_endpoint *endpt, 
    316                                               const pj_str_t *prm_keyfile, 
    317                                               const pj_str_t *prm_password, 
    318                                               const pj_str_t *prm_ca_list_file, 
    319                                               const pj_sockaddr_in *local, 
    320                                               const pjsip_host_port *a_name, 
    321                                               unsigned async_cnt, 
    322                                               pjsip_tpfactory **p_factory) 
    323 { 
    324     struct tls_listener *lis = NULL; 
    325     pj_pool_t *pool = NULL; 
    326     char str_keyfile[256], *keyfile; 
    327     char str_ca_list_file[256], *ca_list_file; 
    328     char str_password[128], *password; 
    329     pj_status_t status; 
    330  
    331     PJ_LOG(5,(THIS_FILE, "Creating TLS listener")); 
    332  
    333     /* Sanity check */ 
    334     PJ_ASSERT_RETURN(endpt, PJ_EINVAL); 
    335  
    336     /* Unused arguments */ 
    337     PJ_UNUSED_ARG(async_cnt); 
    338  
    339 #define COPY_STRING(dstbuf, dst, src)   \ 
    340     if (src) {  \ 
    341         PJ_ASSERT_RETURN(src->slen < sizeof(dstbuf), PJ_ENAMETOOLONG); \ 
    342         pj_memcpy(dstbuf, src->ptr, src->slen); \ 
    343         dstbuf[src->slen] = '\0'; \ 
    344         dst = dstbuf; \ 
    345     } else { \ 
    346         dst = NULL; \ 
    347     } 
    348  
    349     /* Copy strings */ 
    350     COPY_STRING(str_keyfile, keyfile, prm_keyfile); 
    351     COPY_STRING(str_ca_list_file, ca_list_file, prm_ca_list_file); 
    352     COPY_STRING(str_password, password, prm_password); 
    353  
    354     /* Verify that address given in a_name (if any) is valid */ 
    355     if (a_name && a_name->host.slen) { 
    356         pj_sockaddr_in tmp; 
    357  
    358         status = pj_sockaddr_in_init(&tmp, &a_name->host,  
    359                                      (pj_uint16_t)a_name->port); 
    360         if (status != PJ_SUCCESS || tmp.sin_addr.s_addr == PJ_INADDR_ANY || 
    361             tmp.sin_addr.s_addr == PJ_INADDR_NONE) 
    362         { 
    363             /* Invalid address */ 
    364             return PJ_EINVAL; 
    365         } 
    366     } 
    367  
    368     /* Initialize OpenSSL */ 
    369     status = init_openssl(); 
    370     if (status != PJ_SUCCESS) 
    371         return status; 
    372  
    373  
    374     /* Create the listener struct. */ 
    375     pool = pjsip_endpt_create_pool(endpt, "tlslis", 4000, 4000); 
    376     lis = pj_pool_zalloc(pool, sizeof(*lis)); 
    377     lis->base.pool = pool; 
    378  
    379     /* Save password */ 
    380     pj_strdup2_with_null(pool, &lis->password, password); 
    381  
    382  
    383     /* Create OpenSSL context */ 
    384     status = initialize_ctx(lis, keyfile, ca_list_file, &lis->ctx); 
    385     if (status != PJ_SUCCESS) 
    386         goto on_error; 
    387  
    388     /* Initialize listener. */ 
    389     pj_ansi_snprintf(lis->base.obj_name, sizeof(lis->base.obj_name),  
    390                      "%s", "tlslis"); 
    391     pj_lock_create_recursive_mutex(pool, "tlslis", &lis->base.lock); 
    392     lis->base.type = PJSIP_TRANSPORT_TLS; 
    393     lis->base.type_name = "tls"; 
    394     lis->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); 
    395     lis->base.create_transport = &lis_create_transport; 
    396     lis->base.destroy = &lis_destroy; 
    397  
    398     /* Keep endpoint and transport manager instance */ 
    399     lis->endpt = endpt; 
    400     lis->tpmgr = pjsip_endpt_get_tpmgr(endpt); 
    401  
    402     /* Determine the exported name */ 
    403     if (a_name) { 
    404         pj_strdup(pool, &lis->base.addr_name.host, &a_name->host); 
    405         lis->base.addr_name.port = a_name->port; 
    406     } else { 
    407         pj_in_addr ip_addr; 
    408         const char *str_ip_addr; 
    409  
    410         /* Get default IP interface for the host */ 
    411         status = pj_gethostip(&ip_addr); 
    412         if (status != PJ_SUCCESS) 
    413             goto on_error; 
    414  
    415         /* Set publicized host */ 
    416         str_ip_addr = pj_inet_ntoa(ip_addr); 
    417         pj_strdup2(pool, &lis->base.addr_name.host, str_ip_addr); 
    418  
    419         /* Set publicized port */ 
    420         if (local) { 
    421             lis->base.addr_name.port = pj_ntohs(local->sin_port); 
    422         } else { 
    423             lis->base.addr_name.port =  
    424                 pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_TLS); 
    425         } 
    426     } 
    427  
    428 #if 0 
    429     if (local) { 
    430         pj_memcpy(&lis->base.local_addr, local, sizeof(pj_sockaddr_in)); 
    431         pj_strdup2(pool, &lis->base.addr_name.host,  
    432                    pj_inet_ntoa(((pj_sockaddr_in*)local)->sin_addr)); 
    433         lis->base.addr_name.port = pj_ntohs(((pj_sockaddr_in*)local)->sin_port); 
    434     } else { 
    435         int port; 
    436         port = pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_TLS); 
    437         pj_sockaddr_in_init(&lis->base.local_addr, NULL, port); 
    438         pj_strdup(pool, &lis->base.addr_name.host, pj_gethostname()); 
    439         lis->base.addr_name.port = port; 
    440     } 
    441 #endif 
    442  
    443  
    444     /* Register listener to transport manager. */ 
    445     status = pjsip_tpmgr_register_tpfactory(lis->tpmgr, &lis->base); 
    446     if (status != PJ_SUCCESS) 
    447         goto on_error; 
    448  
    449     lis->is_registered = PJ_TRUE; 
    450  
    451  
    452     /* Done */ 
    453     if (p_factory) 
    454         *p_factory = &lis->base; 
    455  
    456     PJ_LOG(4,(lis->base.obj_name, "TLS listener started at %.*s;%d", 
    457               (int)lis->base.addr_name.host.slen, 
    458               lis->base.addr_name.host.ptr, 
    459               lis->base.addr_name.port)); 
    460     return PJ_SUCCESS; 
    461  
    462 on_error: 
    463     if (lis) { 
    464         lis_destroy(&lis->base); 
    465     } else if (pool) { 
    466         pj_pool_release(pool); 
    467         shutdown_openssl(); 
    468     } else { 
    469         shutdown_openssl(); 
    470     } 
    471  
    472     return status; 
    473 } 
    474  
    475  
    476 /* Transport worker thread */ 
    477 static int PJ_THREAD_FUNC tls_worker_thread(void *arg) 
    478 { 
    479     struct tls_transport *tls_tp = (struct tls_transport *)arg; 
    480     pjsip_rx_data *rdata = &tls_tp->rdata; 
    481  
    482     while (!tls_tp->quitting) { 
    483         pj_fd_set_t rd_set; 
    484         pj_time_val timeout; 
    485         int len; 
    486         pj_size_t size_eaten; 
    487  
    488         PJ_FD_ZERO(&rd_set); 
    489         PJ_FD_SET(tls_tp->sock, &rd_set); 
    490  
    491         timeout.sec = 1; 
    492         timeout.msec = 0; 
    493  
    494         len = pj_sock_select(tls_tp->sock, &rd_set, NULL, NULL, &timeout); 
    495         if (len < 1) 
    496             continue; 
    497  
    498         /* Start blocking read to SSL socket */ 
    499         len = SSL_read(tls_tp->ssl,  
    500                        rdata->pkt_info.packet + rdata->pkt_info.len, 
    501                        sizeof(rdata->pkt_info.packet) - rdata->pkt_info.len); 
    502  
    503  
    504         switch (SSL_get_error(tls_tp->ssl, len)) { 
    505         case SSL_ERROR_NONE: 
    506             rdata->pkt_info.len += len; 
    507             rdata->pkt_info.zero = 0; 
    508             pj_gettimeofday(&rdata->pkt_info.timestamp); 
    509  
    510             /* Report to transport manager. 
    511              * The transport manager will tell us how many bytes of the packet 
    512              * have been processed (as valid SIP message). 
    513              */ 
    514             size_eaten =  
    515                 pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr,  
    516                                            rdata); 
    517  
    518             pj_assert(size_eaten <= (pj_size_t)rdata->pkt_info.len); 
    519  
    520             /* Move unprocessed data to the front of the buffer */ 
    521             if (size_eaten>0 && size_eaten<(pj_size_t)rdata->pkt_info.len) { 
    522                 pj_memmove(rdata->pkt_info.packet, 
    523                            rdata->pkt_info.packet + size_eaten, 
    524                            rdata->pkt_info.len - size_eaten); 
    525             } 
    526              
    527             rdata->pkt_info.len -= size_eaten; 
    528             break; 
    529  
    530         case SSL_ERROR_ZERO_RETURN: 
    531             PJ_LOG(4,(tls_tp->base.obj_name, "SSL transport shutdodwn by remote")); 
    532             if (!tls_tp->quitting) 
    533                 pjsip_transport_shutdown(&tls_tp->base); 
    534             goto done; 
    535  
    536         case SSL_ERROR_SYSCALL: 
    537             PJ_LOG(2,(tls_tp->base.obj_name, "SSL Error: Premature close")); 
    538             if (!tls_tp->quitting) 
    539                 pjsip_transport_shutdown(&tls_tp->base); 
    540             goto done; 
    541  
    542         default: 
    543             PJ_LOG(2,(tls_tp->base.obj_name, "SSL read problem")); 
    544             if (!tls_tp->quitting) 
    545                 pjsip_transport_shutdown(&tls_tp->base); 
    546             goto done; 
    547         } 
    548     } 
    549  
    550 done: 
    551     return 0; 
    552 } 
    553  
    554  
    555 PJ_DECL(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp); 
     475    shutdown_openssl(); 
     476} 
    556477 
    557478/* 
    558479 * Perform SSL_connect upon completion of socket connect() 
    559480 */ 
    560 static pj_status_t perform_ssl_connect(SSL *ssl, pj_sock_t sock) 
    561 { 
     481static pj_status_t ssl_connect(struct tls_transport *tls) 
     482{ 
     483    SSL *ssl = tls->ssl; 
    562484    int status; 
    563485 
     
    565487        return PJ_SUCCESS; 
    566488 
    567     SSL_set_fd(ssl, (int)sock); 
    568  
    569     if (!SSL_in_connect_init (ssl)) 
    570         SSL_set_connect_state (ssl); 
     489    if (SSL_get_fd(ssl) < 0) 
     490        SSL_set_fd(ssl, (int)tls->sock); 
     491 
     492    if (!SSL_in_connect_init(ssl)) 
     493        SSL_set_connect_state(ssl); 
     494 
     495    PJ_LOG(5,(tls->base.obj_name, "Starting SSL_connect() negotiation")); 
    571496 
    572497    do { 
     
    585510            /* Success */ 
    586511            status = 0; 
     512            PJ_LOG(5,(tls->base.obj_name,  
     513                      "SSL_connect() negotiation completes successfully")); 
    587514            break; 
    588515 
    589516        case SSL_ERROR_WANT_WRITE: 
    590517            /* Wait for more activity */ 
    591             PJ_FD_SET(sock, &wr_set); 
     518            PJ_FD_SET(tls->sock, &wr_set); 
    592519            status = 1; 
    593520            break; 
     
    595522        case SSL_ERROR_WANT_READ: 
    596523            /* Wait for more activity */ 
    597             PJ_FD_SET(sock, &rd_set); 
     524            PJ_FD_SET(tls->sock, &rd_set); 
    598525            status = 1; 
    599526            break; 
     
    606533            PJ_LOG(4,(THIS_FILE, "SSL connect() failed, remote has" 
    607534                                 "shutdown connection.")); 
    608             status = -1; 
    609             break; 
     535            return PJ_STATUS_FROM_OS(OSERR_ENOTCONN); 
    610536             
    611537        case SSL_ERROR_SYSCALL: 
     
    628554                status = 1;               /* Wait for more activity */ 
    629555                if (SSL_want_write (ssl)) 
    630                     PJ_FD_SET(sock, &wr_set); 
     556                    PJ_FD_SET(tls->sock, &wr_set); 
    631557                else if (SSL_want_read (ssl)) 
    632                     PJ_FD_SET(sock, &rd_set); 
     558                    PJ_FD_SET(tls->sock, &rd_set); 
    633559                else 
    634560                    status = -1;        /* Doesn't want anything - bail out */ 
     
    638564            } 
    639565            break; 
    640              
     566 
    641567        default: 
    642             ssl_report_error(4, THIS_FILE, "SSL_connect() error"); 
     568            ssl_report_error(tls->base.obj_name, 4, PJ_SUCCESS, 
     569                             "SSL_connect() error"); 
    643570            status = -1; 
    644571            break; 
     
    646573         
    647574        if (status == 1) { 
     575            pj_time_val timeout, *p_timeout; 
     576 
    648577            /* Must have at least one handle to wait for at this point. */ 
    649             pj_assert(PJ_FD_COUNT(&rd_set) == 1 ||  
    650                       PJ_FD_COUNT(&wr_set) == 1); 
     578            pj_assert(PJ_FD_COUNT(&rd_set) == 1 || PJ_FD_COUNT(&wr_set) == 1); 
    651579             
     580            /* This will block the whole stack!!! */ 
     581            PJ_TODO(SUPPORT_SSL_ASYNCHRONOUS_CONNECT); 
     582 
     583            if (tls->listener->setting.timeout.sec == 0 && 
     584                tls->listener->setting.timeout.msec == 0) 
     585            { 
     586                p_timeout = NULL; 
     587            } else { 
     588                timeout = tls->listener->setting.timeout; 
     589                p_timeout = &timeout; 
     590            } 
     591 
    652592            /* Block indefinitely if timeout pointer is zero. */ 
    653             status = pj_sock_select(FD_SETSIZE, &rd_set, &wr_set, 
    654                                     NULL, NULL); 
     593            status = pj_sock_select(tls->sock+1, &rd_set, &wr_set, 
     594                                    NULL, p_timeout); 
    655595                     
    656596            /* 0 is timeout, so we're done. 
     
    660600            if (status >= 1) 
    661601                status = 1; 
    662             else                 /* Timeout or socket failure */ 
     602            else if (status == 0) 
     603                return PJSIP_TLS_ETIMEDOUT; 
     604            else 
    663605                status = -1; 
    664606        } 
     
    671613 
    672614/* 
    673  * Create a new TLS transport. The TLS role can be a server or a client, 
    674  * depending on whether socket is valid. 
    675  */ 
    676 static pj_status_t tls_create_transport(struct tls_listener *lis, 
    677                                         pj_sock_t sock, 
    678                                         const pj_sockaddr_in *rem_addr, 
    679                                         struct tls_transport **p_tp) 
    680 { 
    681     struct tls_transport *tls_tp = NULL; 
    682     pj_pool_t *pool = NULL; 
    683     char dst_str[80]; 
    684     int len; 
     615 * Perform SSL_accept() on the newly established incoming TLS connection. 
     616 */ 
     617static pj_status_t ssl_accept(struct tls_transport *tls) 
     618{ 
     619    SSL *ssl = tls->ssl; 
     620    int rc; 
     621     
     622    if (SSL_is_init_finished (ssl)) 
     623        return PJ_SUCCESS; 
     624     
     625    if (!SSL_in_accept_init(ssl)) 
     626        SSL_set_accept_state(ssl); 
     627 
     628    PJ_LOG(5,(tls->base.obj_name, "Starting SSL_accept() negotiation")); 
     629 
     630    /* Repeat retrying SSL_accept() procedure until it completes either 
     631     * successfully or with failure. 
     632     */ 
     633    do { 
     634 
     635        /* These handle sets are used to set up for whatever SSL_accept says 
     636         * it wants next. They're reset on each pass around the loop. 
     637         */ 
     638        pj_fd_set_t rd_set; 
     639        pj_fd_set_t wr_set; 
     640         
     641        PJ_FD_ZERO(&rd_set); 
     642        PJ_FD_ZERO(&wr_set); 
     643 
     644        rc = SSL_accept (ssl); 
     645 
     646        switch (SSL_get_error (ssl, rc)) { 
     647        case SSL_ERROR_NONE: 
     648            /* Success! */ 
     649            rc = 0; 
     650            PJ_LOG(5,(tls->base.obj_name,  
     651                      "SSL_accept() negotiation completes successfully")); 
     652            break; 
     653             
     654        case SSL_ERROR_WANT_WRITE: 
     655            PJ_FD_SET(tls->sock, &wr_set); 
     656            rc = 1;               /* Wait for more activity */ 
     657            break; 
     658             
     659        case SSL_ERROR_WANT_READ: 
     660            PJ_FD_SET(tls->sock, &rd_set); 
     661            rc = 1;               /* Need to read more data */ 
     662            break; 
     663 
     664        case SSL_ERROR_ZERO_RETURN: 
     665            /* The peer has notified us that it is shutting down via the SSL  
     666             * "close_notify" message so we need to shutdown, too. 
     667             */ 
     668            PJ_LOG(4,(tls->base.obj_name,   
     669                      "Incoming SSL connection closed prematurely by client")); 
     670            return PJ_STATUS_FROM_OS(OSERR_ENOTCONN); 
     671 
     672        case SSL_ERROR_SYSCALL: 
     673            /* Explicitly check for EWOULDBLOCK since it doesn't get converted 
     674             * to an SSL_ERROR_WANT_{READ,WRITE} on some platforms.  
     675             * If SSL_accept failed outright, though, don't bother checking  
     676             * more. This can happen if the socket gets closed during the  
     677             * handshake. 
     678             */ 
     679            if (pj_get_netos_error()==PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)  
     680                && rc==-1) 
     681            { 
     682                /* Although the SSL_ERROR_WANT_READ/WRITE isn't getting set  
     683                 * correctly, the read/write state should be valid. Use that  
     684                 * to decide what to do. 
     685                 */ 
     686                rc = 1;               /* Wait for more activity */ 
     687                if (SSL_want_write(ssl)) 
     688                    PJ_FD_SET(tls->sock, &wr_set); 
     689                else if (SSL_want_read(ssl)) 
     690                    PJ_FD_SET(tls->sock, &rd_set); 
     691                else { 
     692                    /* Doesn't want anything - bail out */ 
     693                    return PJ_STATUS_FROM_OS(OSERR_ENOTCONN); 
     694                } 
     695            } 
     696            else { 
     697                return PJSIP_TLS_EUNKNOWN; 
     698            } 
     699            break; 
     700             
     701        default: 
     702            ssl_report_error(tls->base.obj_name, 4, PJ_SUCCESS, 
     703                             "Error calling SSL_accept()"); 
     704            return pj_get_netos_error() ? pj_get_netos_error() :  
     705                    PJSIP_TLS_EUNKNOWN; 
     706        } 
     707         
     708        if (rc == 1) { 
     709 
     710            pj_time_val timeout, *p_timeout; 
     711 
     712            /* Must have at least one handle to wait for at this point. */ 
     713            pj_assert(PJ_FD_COUNT(&rd_set) == 1 || PJ_FD_COUNT(&wr_set) == 1); 
     714 
     715            if (tls->listener->setting.timeout.sec == 0 && 
     716                tls->listener->setting.timeout.msec == 0) 
     717            { 
     718                p_timeout = NULL; 
     719            } else { 
     720                timeout = tls->listener->setting.timeout; 
     721                p_timeout = &timeout; 
     722            } 
     723 
     724            rc = pj_sock_select(tls->sock+1, &rd_set, &wr_set, NULL,  
     725                                p_timeout); 
     726             
     727            if (rc >= 1) 
     728                rc = 1; 
     729            else if (rc == 0) 
     730                return PJSIP_TLS_ETIMEDOUT; 
     731            else 
     732                return pj_get_netos_error(); 
     733        } 
     734         
     735    } while (rc == 1 && !SSL_is_init_finished(ssl)); 
     736     
     737    return (rc == -1 ? PJSIP_TLS_EUNKNOWN : PJ_SUCCESS); 
     738} 
     739 
     740 
     741/* Send outgoing data with SSL connection */ 
     742static pj_status_t ssl_write(struct tls_transport *tls, 
     743                             pjsip_tx_data *tdata) 
     744{ 
     745    int size = tdata->buf.cur - tdata->buf.start; 
     746    int sent = 0; 
     747 
     748    do { 
     749        const int fragment_sent = SSL_write(tls->ssl, 
     750                                            tdata->buf.start + sent,  
     751                                            size - sent); 
     752     
     753        switch( SSL_get_error(tls->ssl, fragment_sent)) { 
     754        case SSL_ERROR_NONE: 
     755            sent += fragment_sent; 
     756            break; 
     757             
     758        case SSL_ERROR_WANT_READ: 
     759        case SSL_ERROR_WANT_WRITE: 
     760            /* For now, we can't handle situation where WANT_READ/WANT_WRITE 
     761             * is raised after some data has been sent, since we don't have 
     762             * mechanism to keep track of how many bytes have been sent 
     763             * inside the individual tdata. 
     764             */ 
     765            pj_assert(sent == 0); 
     766            PJ_TODO(PARTIAL_SSL_SENT); 
     767            return PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK); 
     768             
     769        case SSL_ERROR_ZERO_RETURN: 
     770            /* The peer has notified us that it is shutting down via the SSL 
     771             * "close_notify" message. Tell the transport manager that it 
     772             * shouldn't use this transport any more and return ENOTCONN 
     773             * to caller. 
     774             */ 
     775             
     776            /* It is safe to call this multiple times. */ 
     777            pjsip_transport_shutdown(&tls->base); 
     778 
     779            return PJ_STATUS_FROM_OS(OSERR_ENOTCONN); 
     780             
     781        case SSL_ERROR_SYSCALL: 
     782            if (fragment_sent == 0) { 
     783                /* An EOF occured but the SSL "close_notify" message was not 
     784                 * sent. Shutdown the transport and return ENOTCONN. 
     785                 */ 
     786 
     787                /* It is safe to call this multiple times. */ 
     788                pjsip_transport_shutdown(&tls->base); 
     789 
     790                return PJ_STATUS_FROM_OS(OSERR_ENOTCONN); 
     791            } 
     792             
     793            /* Other error */ 
     794            return pj_get_netos_error(); 
     795 
     796        default: 
     797            ssl_report_error(tls->base.obj_name, 4, PJ_SUCCESS, 
     798                             "Error sending %s with SSL_write()", 
     799                             pjsip_tx_data_get_info(tdata)); 
     800            return pj_get_netos_error() ? pj_get_netos_error()  
     801                    : PJSIP_TLS_ESEND; 
     802        } 
     803     
     804    } while (sent < size); 
     805 
     806    return PJ_SUCCESS; 
     807} 
     808 
     809 
     810/* Read data from SSL connection */ 
     811static pj_status_t ssl_read(struct tls_transport *tls) 
     812{ 
     813    pjsip_rx_data *rdata = &tls->rdata; 
     814 
     815    int bytes_read, max_size; 
     816 
     817    max_size = sizeof(rdata->pkt_info.packet) - rdata->pkt_info.len; 
     818    bytes_read = SSL_read(tls->ssl,  
     819                          rdata->pkt_info.packet+rdata->pkt_info.len, 
     820                          max_size); 
     821 
     822    switch (SSL_get_error(tls->ssl, bytes_read)) { 
     823    case SSL_ERROR_NONE: 
     824        /* Data successfully read */ 
     825        rdata->pkt_info.len += bytes_read; 
     826        return PJ_SUCCESS; 
     827         
     828    case SSL_ERROR_WANT_READ: 
     829    case SSL_ERROR_WANT_WRITE: 
     830        return PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK); 
     831         
     832    case SSL_ERROR_ZERO_RETURN: 
     833        /* The peer has notified us that it is shutting down via the SSL 
     834         * "close_notify" message. 
     835         */ 
     836        pjsip_transport_shutdown(&tls->base); 
     837        return PJ_STATUS_FROM_OS(OSERR_ENOTCONN); 
     838         
     839    case SSL_ERROR_SYSCALL: 
     840        if (bytes_read == 0) { 
     841            /* An EOF occured but the SSL "close_notify" message was not 
     842             * sent. 
     843             */ 
     844            pjsip_transport_shutdown(&tls->base); 
     845            return PJ_STATUS_FROM_OS(OSERR_ENOTCONN); 
     846        } 
     847         
     848        /* Other error */ 
     849        return pj_get_netos_error(); 
     850         
     851    default: 
     852        ssl_report_error(tls->base.obj_name, 4, PJ_SUCCESS, 
     853                         "Error reading data with SSL_read()"); 
     854        return pj_get_netos_error() ? pj_get_netos_error()  
     855                : PJSIP_TLS_EREAD; 
     856    } 
     857 
     858    /* Should not reach here */ 
     859} 
     860 
     861 
     862/**************************************************************************** 
     863 * The TLS listener/transport factory. 
     864 */ 
     865 
     866/* 
     867 * This is the public API to create, initialize, register, and start the 
     868 * TLS listener. 
     869 */ 
     870PJ_DEF(pj_status_t) pjsip_tls_transport_start( pjsip_endpoint *endpt, 
     871                                               const pjsip_tls_setting *opt, 
     872                                               const pj_sockaddr_in *local, 
     873                                               const pjsip_host_port *a_name, 
     874                                               unsigned async_cnt, 
     875                                               pjsip_tpfactory **p_factory) 
     876{ 
     877    pj_pool_t *pool; 
     878    struct tls_listener *listener; 
     879    pj_ioqueue_callback listener_cb; 
     880    pj_sockaddr_in *listener_addr; 
     881    int addr_len; 
     882    unsigned i; 
    685883    pj_status_t status; 
    686884 
    687     /* Build remote address */ 
    688     PJ_ASSERT_RETURN(rem_addr->sin_family==PJ_AF_INET, PJ_EINVAL); 
    689  
    690     /* sock must not be zero (should be either a valid socket or 
    691      * PJ_INVALID_SOCKET. 
    692      */ 
    693     PJ_ASSERT_RETURN(sock==PJ_INVALID_SOCKET || sock > 0, PJ_EINVAL); 
    694  
    695     /*  
    696      * Create the transport  
    697      */ 
    698     pool = pjsip_endpt_create_pool(lis->endpt, "tls", 4000, 4000); 
    699     tls_tp = pj_pool_zalloc(pool, sizeof(*tls_tp)); 
    700     tls_tp->sock = sock; 
    701     tls_tp->base.pool = pool; 
    702  
    703     len = pj_ansi_snprintf(tls_tp->base.obj_name,  
    704                            sizeof(tls_tp->base.obj_name), 
    705                            "tls%p", tls_tp); 
    706     if (len < 1 || len >= sizeof(tls_tp->base.obj_name)) { 
    707         status = PJ_ENAMETOOLONG; 
    708         goto on_error; 
    709     } 
    710  
    711     /* Print destination address. */ 
    712     len = pj_ansi_snprintf(dst_str, sizeof(dst_str), "%s:%d", 
    713                            pj_inet_ntoa(rem_addr->sin_addr),  
    714                            pj_ntohs(rem_addr->sin_port)); 
    715  
    716     PJ_LOG(5,(lis->base.obj_name, "Creating TLS transport to %s", dst_str)); 
    717  
    718  
    719     /* Transport info */ 
    720     tls_tp->base.endpt = lis->endpt; 
    721     tls_tp->base.tpmgr = lis->tpmgr; 
    722     tls_tp->base.type_name = (char*)pjsip_transport_get_type_name(PJSIP_TRANSPORT_TLS); 
    723     tls_tp->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); 
    724     tls_tp->base.info = pj_pool_alloc(pool, len + 5); 
    725     pj_ansi_snprintf(tls_tp->base.info, len + 5, "TLS:%s", dst_str); 
    726  
    727     /* Reference counter */ 
    728     status = pj_atomic_create(pool, 0, &tls_tp->base.ref_cnt); 
     885    /* Sanity check */ 
     886    PJ_ASSERT_RETURN(endpt && async_cnt, PJ_EINVAL); 
     887 
     888    /* Verify that address given in a_name (if any) is valid */ 
     889    if (a_name && a_name->host.slen) { 
     890        pj_sockaddr_in tmp; 
     891 
     892        status = pj_sockaddr_in_init(&tmp, &a_name->host,  
     893                                     (pj_uint16_t)a_name->port); 
     894        if (status != PJ_SUCCESS || tmp.sin_addr.s_addr == PJ_INADDR_ANY || 
     895            tmp.sin_addr.s_addr == PJ_INADDR_NONE) 
     896        { 
     897            /* Invalid address */ 
     898            return PJ_EINVAL; 
     899        } 
     900    } 
     901 
     902    pool = pjsip_endpt_create_pool(endpt, "tlslis", POOL_LIS_INIT,  
     903                                   POOL_LIS_INC); 
     904    PJ_ASSERT_RETURN(pool, PJ_ENOMEM); 
     905 
     906 
     907    listener = pj_pool_zalloc(pool, sizeof(struct tls_listener)); 
     908    listener->factory.pool = pool; 
     909    listener->factory.type = PJSIP_TRANSPORT_TLS; 
     910    listener->factory.type_name = "tls"; 
     911    listener->factory.flag =  
     912        pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); 
     913    listener->sock = PJ_INVALID_SOCKET; 
     914     
     915    /* Create object name */ 
     916    pj_ansi_snprintf(listener->factory.obj_name,  
     917                     sizeof(listener->factory.obj_name), 
     918                     "tls%p",  listener); 
     919     
     920    /* Create duplicate of TLS settings */ 
     921    if (opt) 
     922        pjsip_tls_setting_copy(pool, &listener->setting, opt); 
     923    else 
     924        pjsip_tls_setting_default(&listener->setting); 
     925 
     926    /* Initialize SSL context to be used by this listener */ 
     927    status = create_ctx(listener, &listener->ctx); 
    729928    if (status != PJ_SUCCESS) 
    730929        goto on_error; 
    731      
    732     /* Lock */ 
    733     status = pj_lock_create_recursive_mutex(pool, "tls", &tls_tp->base.lock); 
     930 
     931    status = pj_lock_create_recursive_mutex(pool, "tlslis",  
     932                                            &listener->factory.lock); 
    734933    if (status != PJ_SUCCESS) 
    735934        goto on_error; 
    736935 
    737     /* Transport key */ 
    738     tls_tp->base.key.type = PJSIP_TRANSPORT_TLS; 
    739     pj_memcpy(&tls_tp->base.key.rem_addr, rem_addr, sizeof(*rem_addr)); 
    740  
    741     pj_strdup(pool, &tls_tp->base.local_name.host, &lis->base.addr_name.host); 
    742     tls_tp->base.local_name.port = lis->base.addr_name.port; 
    743  
    744     pj_strdup2(pool, &tls_tp->base.remote_name.host, dst_str); 
    745     tls_tp->base.remote_name.port = pj_ntohs(rem_addr->sin_port); 
    746  
    747     /* Initialize transport callback */ 
    748     tls_tp->base.send_msg = &tls_tp_send_msg; 
    749     tls_tp->base.do_shutdown = &tls_tp_do_shutdown; 
    750     tls_tp->base.destroy = &tls_tp_destroy; 
    751  
    752  
    753     /* Connect SSL */ 
    754     if (sock == PJ_INVALID_SOCKET) { 
    755  
    756         /* Create socket */ 
    757         status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_STREAM, 0, &sock); 
    758         if (status != PJ_SUCCESS) 
    759             goto on_error; 
    760  
    761         /* Save the socket */ 
    762         tls_tp->sock = sock; 
    763  
    764         /* TODO: asynchronous connect() */ 
    765         PJ_TODO(TLS_ASYNC_CONNECT); 
    766  
    767         /* Connect socket */ 
    768         status = pj_sock_connect(sock, rem_addr, sizeof(*rem_addr)); 
    769         if (status != PJ_SUCCESS) 
    770             goto on_error; 
    771  
    772         /* Create SSL object and BIO */ 
    773         tls_tp->ssl = SSL_new(lis->ctx); 
    774         SSL_set_verify (tls_tp->ssl, 0, 0); 
    775  
    776         /* Connect SSL */ 
    777         status = perform_ssl_connect(tls_tp->ssl, sock); 
    778         if (status != PJ_SUCCESS) 
    779             goto on_error; 
    780  
    781         /* TODO: check server cert. */ 
    782         PJ_TODO(TLS_CHECK_SERVER_CERT); 
    783 #if 0 
    784         check_cert(ssl,host); 
    785 #endif 
    786  
    787     } else { 
    788         /* 
    789          * This is a server side TLS socket. 
    790          */ 
    791         PJ_TODO(TLS_IMPLEMENT_SERVER); 
    792         status = PJ_ENOTSUP; 
    793         goto on_error; 
    794     } 
    795  
    796     /* Initialize local address */ 
    797     tls_tp->base.addr_len = sizeof(tls_tp->base.local_addr); 
    798     status = pj_sock_getsockname(tls_tp->sock, &tls_tp->base.local_addr, 
    799                                  &tls_tp->base.addr_len); 
     936 
     937    /* Create and bind socket */ 
     938    status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_STREAM, 0, &listener->sock); 
    800939    if (status != PJ_SUCCESS) 
    801940        goto on_error; 
    802941 
    803  
    804     /*  
    805      * Create rdata  
     942    listener_addr = (pj_sockaddr_in*)&listener->factory.local_addr; 
     943    if (local) { 
     944        pj_memcpy(listener_addr, local, sizeof(pj_sockaddr_in)); 
     945    } else { 
     946        pj_sockaddr_in_init(listener_addr, NULL, 0); 
     947    } 
     948 
     949    status = pj_sock_bind(listener->sock, listener_addr,  
     950                          sizeof(pj_sockaddr_in)); 
     951    if (status != PJ_SUCCESS) 
     952        goto on_error; 
     953 
     954    /* Retrieve the bound address */ 
     955    addr_len = sizeof(pj_sockaddr_in); 
     956    status = pj_sock_getsockname(listener->sock, listener_addr, &addr_len); 
     957    if (status != PJ_SUCCESS) 
     958        goto on_error; 
     959 
     960    /* If published host/IP is specified, then use that address as the 
     961     * listener advertised address. 
    806962     */ 
    807     pool = pjsip_endpt_create_pool(lis->endpt, 
     963    if (a_name && a_name->host.slen) { 
     964        /* Copy the address */ 
     965        listener->factory.addr_name = *a_name; 
     966        pj_strdup(listener->factory.pool, &listener->factory.addr_name.host,  
     967                  &a_name->host); 
     968        listener->factory.addr_name.port = a_name->port; 
     969 
     970    } else { 
     971        /* No published address is given, use the bound address */ 
     972 
     973        /* If the address returns 0.0.0.0, use the default 
     974         * interface address as the transport's address. 
     975         */ 
     976        if (listener_addr->sin_addr.s_addr == 0) { 
     977            pj_in_addr hostip; 
     978 
     979            status = pj_gethostip(&hostip); 
     980            if (status != PJ_SUCCESS) 
     981                goto on_error; 
     982 
     983            listener_addr->sin_addr = hostip; 
     984        } 
     985 
     986        /* Save the address name */ 
     987        sockaddr_to_host_port(listener->factory.pool,  
     988                              &listener->factory.addr_name, listener_addr); 
     989    } 
     990 
     991    /* If port is zero, get the bound port */ 
     992    if (listener->factory.addr_name.port == 0) { 
     993        listener->factory.addr_name.port = pj_ntohs(listener_addr->sin_port); 
     994    } 
     995 
     996    /* Start listening to the address */ 
     997    status = pj_sock_listen(listener->sock, PJSIP_TLS_TRANSPORT_BACKLOG); 
     998    if (status != PJ_SUCCESS) 
     999        goto on_error; 
     1000 
     1001 
     1002    /* Register socket to ioqeuue */ 
     1003    pj_bzero(&listener_cb, sizeof(listener_cb)); 
     1004    listener_cb.on_accept_complete = &on_accept_complete; 
     1005    status = pj_ioqueue_register_sock(pool, pjsip_endpt_get_ioqueue(endpt), 
     1006                                      listener->sock, listener, 
     1007                                      &listener_cb, &listener->key); 
     1008    if (status != PJ_SUCCESS) 
     1009        goto on_error; 
     1010 
     1011    /* Register to transport manager */ 
     1012    listener->endpt = endpt; 
     1013    listener->tpmgr = pjsip_endpt_get_tpmgr(endpt); 
     1014    listener->factory.create_transport = lis_create_transport; 
     1015    listener->factory.destroy = lis_destroy; 
     1016    listener->is_registered = PJ_TRUE; 
     1017    status = pjsip_tpmgr_register_tpfactory(listener->tpmgr, 
     1018                                            &listener->factory); 
     1019    if (status != PJ_SUCCESS) { 
     1020        listener->is_registered = PJ_FALSE; 
     1021        goto on_error; 
     1022    } 
     1023 
     1024 
     1025    /* Start pending accept() operations */ 
     1026    if (async_cnt > MAX_ASYNC_CNT) async_cnt = MAX_ASYNC_CNT; 
     1027    listener->async_cnt = async_cnt; 
     1028 
     1029    for (i=0; i<async_cnt; ++i) { 
     1030        pj_pool_t *pool; 
     1031 
     1032        pool = pjsip_endpt_create_pool(endpt, "tlss%p", POOL_TP_INIT,  
     1033                                       POOL_TP_INIT); 
     1034        if (!pool) { 
     1035            status = PJ_ENOMEM; 
     1036            goto on_error; 
     1037        } 
     1038 
     1039        listener->accept_op[i] = pj_pool_zalloc(pool,  
     1040                                                sizeof(struct pending_accept)); 
     1041        pj_ioqueue_op_key_init(&listener->accept_op[i]->op_key,  
     1042                                sizeof(listener->accept_op[i]->op_key)); 
     1043        listener->accept_op[i]->pool = pool; 
     1044        listener->accept_op[i]->listener = listener; 
     1045        listener->accept_op[i]->index = i; 
     1046 
     1047        on_accept_complete(listener->key, &listener->accept_op[i]->op_key, 
     1048                           listener->sock, PJ_EPENDING); 
     1049    } 
     1050 
     1051    PJ_LOG(4,(listener->factory.obj_name,  
     1052             "SIP TLS listener ready for incoming connections at %.*s:%d", 
     1053             (int)listener->factory.addr_name.host.slen, 
     1054             listener->factory.addr_name.host.ptr, 
     1055             listener->factory.addr_name.port)); 
     1056 
     1057    /* Return the pointer to user */ 
     1058    if (p_factory) *p_factory = &listener->factory; 
     1059 
     1060    return PJ_SUCCESS; 
     1061 
     1062on_error: 
     1063    lis_destroy(&listener->factory); 
     1064    return status; 
     1065} 
     1066 
     1067 
     1068/* This callback is called by transport manager to destroy listener */ 
     1069static pj_status_t lis_destroy(pjsip_tpfactory *factory) 
     1070{ 
     1071    struct tls_listener *listener = (struct tls_listener *)factory; 
     1072    unsigned i; 
     1073 
     1074    if (listener->is_registered) { 
     1075        pjsip_tpmgr_unregister_tpfactory(listener->tpmgr, &listener->factory); 
     1076        listener->is_registered = PJ_FALSE; 
     1077    } 
     1078 
     1079    if (listener->key) { 
     1080        pj_ioqueue_unregister(listener->key); 
     1081        listener->key = NULL; 
     1082        listener->sock = PJ_INVALID_SOCKET; 
     1083    } 
     1084 
     1085    if (listener->sock != PJ_INVALID_SOCKET) { 
     1086        pj_sock_close(listener->sock); 
     1087        listener->sock = PJ_INVALID_SOCKET; 
     1088    } 
     1089 
     1090    if (listener->factory.lock) { 
     1091        pj_lock_destroy(listener->factory.lock); 
     1092        listener->factory.lock = NULL; 
     1093    } 
     1094 
     1095    for (i=0; i<PJ_ARRAY_SIZE(listener->accept_op); ++i) { 
     1096        if (listener->accept_op[i] && listener->accept_op[i]->pool) { 
     1097            pj_pool_t *pool = listener->accept_op[i]->pool; 
     1098            listener->accept_op[i]->pool = NULL; 
     1099            pj_pool_release(pool); 
     1100        } 
     1101    } 
     1102 
     1103    if (listener->ctx) { 
     1104        destroy_ctx(listener->ctx); 
     1105        listener->ctx = NULL; 
     1106    } 
     1107 
     1108    if (listener->factory.pool) { 
     1109        pj_pool_t *pool = listener->factory.pool; 
     1110 
     1111        PJ_LOG(4,(listener->factory.obj_name,  "SIP TLS listener destroyed")); 
     1112 
     1113        listener->factory.pool = NULL; 
     1114        pj_pool_release(pool); 
     1115    } 
     1116 
     1117    return PJ_SUCCESS; 
     1118} 
     1119 
     1120 
     1121/***************************************************************************/ 
     1122/* 
     1123 * TLS Transport 
     1124 */ 
     1125 
     1126/* 
     1127 * Prototypes. 
     1128 */ 
     1129/* Called by transport manager to send message */ 
     1130static pj_status_t tls_send_msg(pjsip_transport *transport,  
     1131                                pjsip_tx_data *tdata, 
     1132                                const pj_sockaddr_t *rem_addr, 
     1133                                int addr_len, 
     1134                                void *token, 
     1135                                void (*callback)(pjsip_transport *transport, 
     1136                                                 void *token,  
     1137                                                 pj_ssize_t sent_bytes)); 
     1138 
     1139/* Called by transport manager to shutdown */ 
     1140static pj_status_t tls_shutdown(pjsip_transport *transport); 
     1141 
     1142/* Called by transport manager to destroy transport */ 
     1143static pj_status_t tls_destroy_transport(pjsip_transport *transport); 
     1144 
     1145/* Utility to destroy transport */ 
     1146static pj_status_t tls_destroy(pjsip_transport *transport, 
     1147                               pj_status_t reason); 
     1148 
     1149/* Callback from ioqueue on incoming packet */ 
     1150static void on_read_complete(pj_ioqueue_key_t *key,  
     1151                             pj_ioqueue_op_key_t *op_key,  
     1152                             pj_ssize_t bytes_read); 
     1153 
     1154/* Callback from ioqueue when packet is sent */ 
     1155static void on_write_complete(pj_ioqueue_key_t *key,  
     1156                              pj_ioqueue_op_key_t *op_key,  
     1157                              pj_ssize_t bytes_sent); 
     1158 
     1159/* Callback from ioqueue when connect completes */ 
     1160static void on_connect_complete(pj_ioqueue_key_t *key,  
     1161                                pj_status_t status); 
     1162 
     1163 
     1164/* 
     1165 * Common function to create TLS transport, called when pending accept() and 
     1166 * pending connect() complete. 
     1167 */ 
     1168static pj_status_t tls_create( struct tls_listener *listener, 
     1169                               pj_pool_t *pool, 
     1170                               pj_sock_t sock, pj_bool_t is_server, 
     1171                               const pj_sockaddr_in *local, 
     1172                               const pj_sockaddr_in *remote, 
     1173                               struct tls_transport **p_tls) 
     1174{ 
     1175    struct tls_transport *tls; 
     1176    pj_ioqueue_t *ioqueue; 
     1177    pj_ioqueue_callback tls_callback; 
     1178    int rc; 
     1179    pj_status_t status; 
     1180     
     1181 
     1182    PJ_ASSERT_RETURN(sock != PJ_INVALID_SOCKET, PJ_EINVAL); 
     1183 
     1184 
     1185    if (pool == NULL) { 
     1186        pool = pjsip_endpt_create_pool(listener->endpt, "tls", 
     1187                                       POOL_TP_INIT, POOL_TP_INC); 
     1188        PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); 
     1189    }     
     1190 
     1191    /* 
     1192     * Create and initialize basic transport structure. 
     1193     */ 
     1194    tls = pj_pool_zalloc(pool, sizeof(*tls)); 
     1195    tls->sock = sock; 
     1196    tls->is_server = is_server; 
     1197    tls->listener = listener; 
     1198    pj_list_init(&tls->delayed_list); 
     1199    tls->base.pool = pool; 
     1200 
     1201    pj_ansi_snprintf(tls->base.obj_name, PJ_MAX_OBJ_NAME,  
     1202                     (is_server ? "tlss%p" :"tlsc%p"), tls); 
     1203 
     1204    /* Initialize transport reference counter to 1 */ 
     1205    status = pj_atomic_create(pool, 1, &tls->base.ref_cnt); 
     1206    if (status != PJ_SUCCESS) { 
     1207        goto on_error; 
     1208    } 
     1209 
     1210    status = pj_lock_create_recursive_mutex(pool, "tls", &tls->base.lock); 
     1211    if (status != PJ_SUCCESS) { 
     1212        goto on_error; 
     1213    } 
     1214 
     1215    tls->base.key.type = PJSIP_TRANSPORT_TLS; 
     1216    pj_memcpy(&tls->base.key.rem_addr, remote, sizeof(pj_sockaddr_in)); 
     1217    tls->base.type_name = "tls"; 
     1218    tls->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); 
     1219 
     1220    tls->base.info = pj_pool_alloc(pool, 64); 
     1221    pj_ansi_snprintf(tls->base.info, 64, "TLS to %s:%d", 
     1222                     pj_inet_ntoa(remote->sin_addr),  
     1223                     (int)pj_ntohs(remote->sin_port)); 
     1224 
     1225    tls->base.addr_len = sizeof(pj_sockaddr_in); 
     1226    pj_memcpy(&tls->base.local_addr, local, sizeof(pj_sockaddr_in)); 
     1227    sockaddr_to_host_port(pool, &tls->base.local_name, local); 
     1228    sockaddr_to_host_port(pool, &tls->base.remote_name, remote); 
     1229 
     1230    tls->base.endpt = listener->endpt; 
     1231    tls->base.tpmgr = listener->tpmgr; 
     1232    tls->base.send_msg = &tls_send_msg; 
     1233    tls->base.do_shutdown = &tls_shutdown; 
     1234    tls->base.destroy = &tls_destroy_transport; 
     1235 
     1236    /* Create SSL connection object */ 
     1237    tls->ssl = SSL_new(listener->ctx); 
     1238    if (tls->ssl == NULL) { 
     1239        ssl_report_error(tls->base.obj_name, 4, PJ_SUCCESS, 
     1240                         "Error creating SSL connection object"); 
     1241        status = PJSIP_TLS_ESSLCONN; 
     1242        goto on_error; 
     1243    } 
     1244 
     1245    /* Associate network socket with SSL connection object */ 
     1246    rc = SSL_set_fd(tls->ssl, (int)sock); 
     1247    if (rc != 1) { 
     1248        ssl_report_error(tls->base.obj_name, 4, PJ_SUCCESS, 
     1249                         "Error calling SSL_set_fd"); 
     1250        status = PJSIP_TLS_ESSLCONN; 
     1251        goto on_error; 
     1252    } 
     1253 
     1254    /* Register socket to ioqueue */ 
     1255    pj_bzero(&tls_callback, sizeof(pj_ioqueue_callback)); 
     1256    tls_callback.on_read_complete = &on_read_complete; 
     1257    tls_callback.on_write_complete = &on_write_complete; 
     1258    tls_callback.on_connect_complete = &on_connect_complete; 
     1259 
     1260    ioqueue = pjsip_endpt_get_ioqueue(listener->endpt); 
     1261    status = pj_ioqueue_register_sock(pool, ioqueue, sock,  
     1262                                      tls, &tls_callback, &tls->key); 
     1263    if (status != PJ_SUCCESS) { 
     1264        goto on_error; 
     1265    } 
     1266 
     1267    /* Register transport to transport manager */ 
     1268    status = pjsip_transport_register(listener->tpmgr, &tls->base); 
     1269    if (status != PJ_SUCCESS) { 
     1270        goto on_error; 
     1271    } 
     1272 
     1273    tls->is_registered = PJ_TRUE; 
     1274 
     1275    /* Done setting up basic transport. */ 
     1276    *p_tls = tls; 
     1277 
     1278    PJ_LOG(4,(tls->base.obj_name, "TLS %s transport created", 
     1279              (tls->is_server ? "server" : "client"))); 
     1280 
     1281    return PJ_SUCCESS; 
     1282 
     1283on_error: 
     1284    tls_destroy(&tls->base, status); 
     1285    return status; 
     1286} 
     1287 
     1288 
     1289/* Flush all delayed transmision once the socket is connected.  
     1290 * Return non-zero if pending transmission list is empty after 
     1291 * the function returns. 
     1292 */ 
     1293static pj_bool_t tls_flush_pending_tx(struct tls_transport *tls) 
     1294{ 
     1295    pj_bool_t empty; 
     1296 
     1297    pj_lock_acquire(tls->base.lock); 
     1298    while (!pj_list_empty(&tls->delayed_list)) { 
     1299        struct delayed_tdata *pending_tx; 
     1300        pjsip_tx_data *tdata; 
     1301        pj_ioqueue_op_key_t *op_key; 
     1302        pj_ssize_t size; 
     1303        pj_status_t status; 
     1304 
     1305        pending_tx = tls->delayed_list.next; 
     1306 
     1307        tdata = pending_tx->tdata_op_key->tdata; 
     1308        op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key; 
     1309 
     1310        /* send the txdata */ 
     1311        status = ssl_write(tls, tdata); 
     1312 
     1313        /* On EWOULDBLOCK, suspend further transmissions */ 
     1314        if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) { 
     1315            break; 
     1316        } 
     1317 
     1318        /* tdata has been transmitted (successfully or with failure). 
     1319         * In any case, remove it from pending transmission list. 
     1320         */ 
     1321        pj_list_erase(pending_tx); 
     1322 
     1323        /* Notify callback */ 
     1324        if (status == PJ_SUCCESS) 
     1325            size = tdata->buf.cur - tdata->buf.start; 
     1326        else 
     1327            size = -status; 
     1328 
     1329        on_write_complete(tls->key, op_key, size); 
     1330 
     1331    } 
     1332 
     1333    empty = pj_list_empty(&tls->delayed_list); 
     1334 
     1335    pj_lock_release(tls->base.lock); 
     1336 
     1337    return empty; 
     1338} 
     1339 
     1340 
     1341/* Called by transport manager to destroy transport */ 
     1342static pj_status_t tls_destroy_transport(pjsip_transport *transport) 
     1343{ 
     1344    struct tls_transport *tls = (struct tls_transport*)transport; 
     1345 
     1346    /* Transport would have been unregistered by now since this callback 
     1347     * is called by transport manager. 
     1348     */ 
     1349    tls->is_registered = PJ_FALSE; 
     1350 
     1351    return tls_destroy(transport, tls->close_reason); 
     1352} 
     1353 
     1354 
     1355/* Destroy TLS transport */ 
     1356static pj_status_t tls_destroy(pjsip_transport *transport,  
     1357                               pj_status_t reason) 
     1358{ 
     1359    struct tls_transport *tls = (struct tls_transport*)transport; 
     1360 
     1361    if (tls->close_reason == 0) 
     1362        tls->close_reason = reason; 
     1363 
     1364    if (tls->is_registered) { 
     1365        tls->is_registered = PJ_FALSE; 
     1366        pjsip_transport_destroy(transport); 
     1367 
     1368        /* pjsip_transport_destroy will recursively call this function 
     1369         * again. 
     1370         */ 
     1371        return PJ_SUCCESS; 
     1372    } 
     1373 
     1374    /* Mark transport as closing */ 
     1375    ++tls->is_closing; 
     1376 
     1377    /* Cancel all delayed transmits */ 
     1378    while (!pj_list_empty(&tls->delayed_list)) { 
     1379        struct delayed_tdata *pending_tx; 
     1380        pj_ioqueue_op_key_t *op_key; 
     1381 
     1382        pending_tx = tls->delayed_list.next; 
     1383        pj_list_erase(pending_tx); 
     1384 
     1385        op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key; 
     1386 
     1387        on_write_complete(tls->key, op_key, -reason); 
     1388    } 
     1389 
     1390    if (tls->rdata.tp_info.pool) { 
     1391        pj_pool_release(tls->rdata.tp_info.pool); 
     1392        tls->rdata.tp_info.pool = NULL; 
     1393    } 
     1394 
     1395    if (tls->key) { 
     1396        pj_ioqueue_unregister(tls->key); 
     1397        tls->key = NULL; 
     1398        tls->sock = PJ_INVALID_SOCKET; 
     1399    } 
     1400 
     1401    if (tls->sock != PJ_INVALID_SOCKET) { 
     1402        pj_sock_close(tls->sock); 
     1403        tls->sock = PJ_INVALID_SOCKET; 
     1404    } 
     1405 
     1406    if (tls->base.lock) { 
     1407        pj_lock_destroy(tls->base.lock); 
     1408        tls->base.lock = NULL; 
     1409    } 
     1410 
     1411    if (tls->base.ref_cnt) { 
     1412        pj_atomic_destroy(tls->base.ref_cnt); 
     1413        tls->base.ref_cnt = NULL; 
     1414    } 
     1415 
     1416    if (tls->ssl) { 
     1417        SSL_free(tls->ssl); 
     1418        tls->ssl = NULL; 
     1419    } 
     1420 
     1421    if (tls->base.pool) { 
     1422        pj_pool_t *pool; 
     1423 
     1424        if (reason != PJ_SUCCESS) { 
     1425            char errmsg[PJ_ERR_MSG_SIZE]; 
     1426 
     1427            pj_strerror(reason, errmsg, sizeof(errmsg)); 
     1428            PJ_LOG(4,(tls->base.obj_name,  
     1429                      "TLS transport destroyed with reason %d: %s",  
     1430                      reason, errmsg)); 
     1431 
     1432        } else { 
     1433 
     1434            PJ_LOG(4,(tls->base.obj_name,  
     1435                      "TLS transport destroyed normally")); 
     1436 
     1437        } 
     1438 
     1439        pool = tls->base.pool; 
     1440        tls->base.pool = NULL; 
     1441        pj_pool_release(pool); 
     1442    } 
     1443 
     1444    return PJ_SUCCESS; 
     1445} 
     1446 
     1447 
     1448/* 
     1449 * This utility function creates receive data buffers and start 
     1450 * asynchronous recv() operations from the socket. It is called after 
     1451 * accept() or connect() operation complete. 
     1452 */ 
     1453static pj_status_t tls_start_read(struct tls_transport *tls) 
     1454{ 
     1455    pj_pool_t *pool; 
     1456    pj_ssize_t size; 
     1457    pj_sockaddr_in *rem_addr; 
     1458    pj_status_t status; 
     1459 
     1460    /* Init rdata */ 
     1461    pool = pjsip_endpt_create_pool(tls->listener->endpt, 
    8081462                                   "rtd%p", 
    8091463                                   PJSIP_POOL_RDATA_LEN, 
    8101464                                   PJSIP_POOL_RDATA_INC); 
    8111465    if (!pool) { 
    812         status = PJ_ENOMEM; 
    813         goto on_error; 
    814     } 
    815     tls_tp->rdata.tp_info.pool = pool; 
    816  
    817     /* 
    818      * Initialize rdata 
     1466        ssl_report_error(tls->base.obj_name, 4, PJ_ENOMEM,  
     1467                         "Unable to create pool for listener rxdata"); 
     1468        return PJ_ENOMEM; 
     1469    } 
     1470 
     1471    tls->rdata.tp_info.pool = pool; 
     1472 
     1473    tls->rdata.tp_info.transport = &tls->base; 
     1474    tls->rdata.tp_info.tp_data = tls; 
     1475    tls->rdata.tp_info.op_key.rdata = &tls->rdata; 
     1476    pj_ioqueue_op_key_init(&tls->rdata.tp_info.op_key.op_key,  
     1477                           sizeof(pj_ioqueue_op_key_t)); 
     1478 
     1479    tls->rdata.pkt_info.src_addr = tls->base.key.rem_addr; 
     1480    tls->rdata.pkt_info.src_addr_len = sizeof(pj_sockaddr_in); 
     1481    rem_addr = (pj_sockaddr_in*) &tls->base.key.rem_addr; 
     1482    pj_ansi_strcpy(tls->rdata.pkt_info.src_name, 
     1483                   pj_inet_ntoa(rem_addr->sin_addr)); 
     1484    tls->rdata.pkt_info.src_port = pj_ntohs(rem_addr->sin_port); 
     1485 
     1486    /* Here's the real trick with OpenSSL. 
     1487     * Since asynchronous socket operation with OpenSSL uses select() like 
     1488     * mechanism, it's not really compatible with PJLIB's ioqueue. So to 
     1489     * make them "talk" together, we simulate select() by using MSG_PEEK 
     1490     * when we call pj_ioqueue_recv(). 
    8191491     */ 
    820     tls_tp->rdata.tp_info.transport = &tls_tp->base; 
    821     tls_tp->rdata.tp_info.tp_data = tls_tp; 
    822     tls_tp->rdata.tp_info.op_key.rdata = &tls_tp->rdata; 
    823     pj_ioqueue_op_key_init(&tls_tp->rdata.tp_info.op_key.op_key,  
    824                            sizeof(pj_ioqueue_op_key_t)); 
    825  
    826     tls_tp->rdata.pkt_info.src_addr = tls_tp->base.key.rem_addr; 
    827     tls_tp->rdata.pkt_info.src_addr_len = sizeof(pj_sockaddr_in); 
    828     rem_addr = (pj_sockaddr_in*) &tls_tp->base.key.rem_addr; 
    829     pj_ansi_strcpy(tls_tp->rdata.pkt_info.src_name, 
    830                    pj_inet_ntoa(rem_addr->sin_addr)); 
    831     tls_tp->rdata.pkt_info.src_port = pj_ntohs(rem_addr->sin_port); 
    832  
    833     /* Register transport to transport manager */ 
    834     status = pjsip_transport_register(lis->tpmgr, &tls_tp->base); 
    835     if (status != PJ_SUCCESS) { 
    836         goto on_error; 
    837     } 
    838  
    839     /* Create worker thread to receive packets */ 
    840     status = pj_thread_create(pool, "tlsthread", &tls_worker_thread, 
    841                               tls_tp, PJ_THREAD_DEFAULT_STACK_SIZE, 0,  
    842                               &tls_tp->thread); 
    843     if (status != PJ_SUCCESS) { 
    844         pjsip_transport_destroy(&tls_tp->base); 
     1492    size = 1; 
     1493    status = pj_ioqueue_recv(tls->key, &tls->rdata.tp_info.op_key.op_key, 
     1494                             tls->rdata.pkt_info.packet, &size, 
     1495                             PJ_IOQUEUE_ALWAYS_ASYNC | PJ_MSG_PEEK); 
     1496    if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
     1497        ssl_report_error(tls->base.obj_name, 4, status, 
     1498                         "ioqueue_recv() error"); 
    8451499        return status; 
    8461500    } 
    8471501 
    848     /* Done */ 
    849     *p_tp = tls_tp; 
    850  
    851     PJ_LOG(4,(tls_tp->base.obj_name, "TLS transport created, remote=%s",  
    852               dst_str)); 
    853  
    8541502    return PJ_SUCCESS; 
    855  
    856 on_error: 
    857     if (tls_tp) 
    858         tls_tp_destroy(&tls_tp->base); 
    859     else if (pool) { 
    860         pj_pool_release(pool); 
    861         if (sock != PJ_INVALID_SOCKET) pj_sock_close(sock); 
    862     } 
    863     return status; 
    864 } 
    865  
    866  
    867 /* 
    868  * Callback from transport manager to create a new (outbound) TLS transport. 
     1503} 
     1504 
     1505 
     1506 
     1507/* This callback is called by transport manager for the TLS factory 
     1508 * to create outgoing transport to the specified destination. 
    8691509 */ 
    8701510static pj_status_t lis_create_transport(pjsip_tpfactory *factory, 
     
    8731513                                        const pj_sockaddr *rem_addr, 
    8741514                                        int addr_len, 
    875                                         pjsip_transport **transport) 
    876 { 
     1515                                        pjsip_transport **p_transport) 
     1516{ 
     1517    struct tls_listener *listener; 
     1518    struct tls_transport *tls; 
     1519    pj_sock_t sock; 
     1520    pj_sockaddr_in local_addr; 
    8771521    pj_status_t status; 
    878     struct tls_transport *tls_tp; 
    879  
    880     /* Check address */ 
     1522 
     1523    /* Sanity checks */ 
     1524    PJ_ASSERT_RETURN(factory && mgr && endpt && rem_addr && 
     1525                     addr_len && p_transport, PJ_EINVAL); 
     1526 
     1527    /* Check that address is a sockaddr_in */ 
    8811528    PJ_ASSERT_RETURN(rem_addr->sa_family == PJ_AF_INET && 
    8821529                     addr_len == sizeof(pj_sockaddr_in), PJ_EINVAL); 
    8831530 
    8841531 
    885     PJ_UNUSED_ARG(mgr); 
    886     PJ_UNUSED_ARG(endpt); 
    887     /* addr_len is not used on Release build */ 
    888     PJ_UNUSED_ARG(addr_len); 
    889  
    890     /* Create TLS transport */ 
    891     status = tls_create_transport((struct tls_listener*)factory,  
    892                                   PJ_INVALID_SOCKET, 
    893                                   (const pj_sockaddr_in*)rem_addr, 
    894                                   &tls_tp); 
     1532    listener = (struct tls_listener*)factory; 
     1533 
     1534     
     1535    /* Create socket */ 
     1536    status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_STREAM, 0, &sock); 
    8951537    if (status != PJ_SUCCESS) 
    8961538        return status; 
    8971539 
     1540    /* Bind to any port */ 
     1541    status = pj_sock_bind_in(sock, 0, 0); 
     1542    if (status != PJ_SUCCESS) { 
     1543        pj_sock_close(sock); 
     1544        return status; 
     1545    } 
     1546 
     1547    /* Get the local port */ 
     1548    addr_len = sizeof(pj_sockaddr_in); 
     1549    status = pj_sock_getsockname(sock, &local_addr, &addr_len); 
     1550    if (status != PJ_SUCCESS) { 
     1551        pj_sock_close(sock); 
     1552        return status; 
     1553    } 
     1554 
     1555    /* Initially set the address from the listener's address */ 
     1556    local_addr.sin_addr.s_addr =  
     1557        ((pj_sockaddr_in*)&listener->factory.local_addr)->sin_addr.s_addr; 
     1558 
     1559    /* Create the transport descriptor */ 
     1560    status = tls_create(listener, NULL, sock, PJ_FALSE, &local_addr,  
     1561                        (pj_sockaddr_in*)rem_addr, &tls); 
     1562    if (status != PJ_SUCCESS) 
     1563        return status; 
     1564 
     1565 
     1566    /* Start asynchronous connect() operation */ 
     1567    tls->has_pending_connect = PJ_TRUE; 
     1568    status = pj_ioqueue_connect(tls->key, rem_addr, sizeof(pj_sockaddr_in)); 
     1569    if (status == PJ_SUCCESS) { 
     1570 
     1571        /* Immediate socket connect() ! */ 
     1572        tls->has_pending_connect = PJ_FALSE; 
     1573 
     1574        /* Perform SSL_connect() */ 
     1575        status = ssl_connect(tls); 
     1576        if (status != PJ_SUCCESS) { 
     1577            tls_destroy(&tls->base, status); 
     1578            return status; 
     1579        } 
     1580 
     1581    } else if (status != PJ_EPENDING) { 
     1582        tls_destroy(&tls->base, status); 
     1583        return status; 
     1584    } 
     1585 
     1586    /* Update (again) local address, just in case local address currently 
     1587     * set is different now that asynchronous connect() is started. 
     1588     */ 
     1589    addr_len = sizeof(pj_sockaddr_in); 
     1590    if (pj_sock_getsockname(tls->sock, &local_addr, &addr_len)==PJ_SUCCESS) { 
     1591        pj_sockaddr_in *tp_addr = (pj_sockaddr_in*)&tls->base.local_addr; 
     1592 
     1593        /* Some systems (like old Win32 perhaps) may not set local address 
     1594         * properly before socket is fully connected. 
     1595         */ 
     1596        if (tp_addr->sin_addr.s_addr != local_addr.sin_addr.s_addr && 
     1597            local_addr.sin_addr.s_addr != 0)  
     1598        { 
     1599            tp_addr->sin_addr.s_addr = local_addr.sin_addr.s_addr; 
     1600            tp_addr->sin_port = local_addr.sin_port; 
     1601            sockaddr_to_host_port(tls->base.pool, &tls->base.local_name, 
     1602                                  &local_addr); 
     1603        } 
     1604    } 
     1605 
     1606    if (tls->has_pending_connect) { 
     1607        PJ_LOG(4,(tls->base.obj_name,  
     1608                  "TLS transport %.*s:%d is connecting to %.*s:%d...", 
     1609                  (int)tls->base.local_name.host.slen, 
     1610                  tls->base.local_name.host.ptr, 
     1611                  tls->base.local_name.port, 
     1612                  (int)tls->base.remote_name.host.slen, 
     1613                  tls->base.remote_name.host.ptr, 
     1614                  tls->base.remote_name.port)); 
     1615    } 
     1616 
    8981617    /* Done */ 
    899     *transport = &tls_tp->base; 
     1618    *p_transport = &tls->base; 
     1619 
    9001620    return PJ_SUCCESS; 
    9011621} 
    9021622 
     1623 
    9031624/* 
    904  * Callback from transport manager to destroy TLS listener. 
    905  */ 
    906 static pj_status_t lis_destroy(pjsip_tpfactory *factory) 
    907 { 
    908     struct tls_listener *lis = (struct tls_listener *) factory; 
    909  
    910     PJ_LOG(4,(factory->obj_name, "TLS listener shutting down..")); 
    911  
    912     if (lis->is_registered) { 
    913         pjsip_tpmgr_unregister_tpfactory(lis->tpmgr, &lis->base); 
    914         lis->is_registered = PJ_FALSE; 
    915     } 
    916  
    917     if (lis->base.lock) { 
    918         pj_lock_destroy(lis->base.lock); 
    919         lis->base.lock = NULL; 
    920     } 
    921  
    922     if (lis->ctx) { 
    923         destroy_ctx(lis->ctx); 
    924         lis->ctx = NULL; 
    925     } 
    926  
    927     if (lis->base.pool) { 
    928         pj_pool_t *pool = lis->base.pool; 
    929         lis->base.pool = NULL; 
    930         pj_pool_release(pool); 
    931     } 
    932  
    933     /* Shutdown OpenSSL */ 
    934     shutdown_openssl(); 
     1625 * This callback is called by ioqueue when pending accept() operation has 
     1626 * completed. 
     1627 */ 
     1628static void on_accept_complete( pj_ioqueue_key_t *key,  
     1629                                pj_ioqueue_op_key_t *op_key,  
     1630                                pj_sock_t sock,  
     1631                                pj_status_t status) 
     1632{ 
     1633    struct tls_listener *listener; 
     1634    struct tls_transport *tls; 
     1635    struct pending_accept *accept_op; 
     1636    int err_cnt = 0; 
     1637 
     1638    listener = pj_ioqueue_get_user_data(key); 
     1639    accept_op = (struct pending_accept*) op_key; 
     1640 
     1641    /* 
     1642     * Loop while there is immediate connection or when there is error. 
     1643     */ 
     1644    do { 
     1645        if (status == PJ_EPENDING) { 
     1646            /* 
     1647             * This can only happen when this function is called during 
     1648             * initialization to kick off asynchronous accept(). 
     1649             */ 
     1650 
     1651        } else if (status != PJ_SUCCESS) { 
     1652 
     1653            /* 
     1654             * Error in accept(). 
     1655             */ 
     1656            ssl_report_error(listener->factory.obj_name, 4, status, 
     1657                             "Error in asynchronous accept() completion"); 
     1658 
     1659            /* 
     1660             * Prevent endless accept() error loop by limiting the 
     1661             * number of consecutive errors. Once the number of errors 
     1662             * is equal to maximum, we treat this as permanent error, and 
     1663             * we stop the accept() operation. 
     1664             */ 
     1665            ++err_cnt; 
     1666            if (err_cnt >= 10) { 
     1667                PJ_LOG(1, (listener->factory.obj_name,  
     1668                           "Too many errors, listener stopping")); 
     1669            } 
     1670 
     1671        } else { 
     1672            pj_pool_t *pool; 
     1673            struct pending_accept *new_op; 
     1674 
     1675            if (sock == PJ_INVALID_SOCKET) { 
     1676                sock = accept_op->new_sock; 
     1677            } 
     1678 
     1679            if (sock == PJ_INVALID_SOCKET) { 
     1680                pj_assert(!"Should not happen. status should be error"); 
     1681                goto next_accept; 
     1682            } 
     1683 
     1684            PJ_LOG(4,(listener->factory.obj_name,  
     1685                      "TLS listener %.*s:%d: got incoming TCP connection " 
     1686                      "from %s:%d, sock=%d", 
     1687                      (int)listener->factory.addr_name.host.slen, 
     1688                      listener->factory.addr_name.host.ptr, 
     1689                      listener->factory.addr_name.port, 
     1690                      pj_inet_ntoa(accept_op->remote_addr.sin_addr), 
     1691                      pj_ntohs(accept_op->remote_addr.sin_port), 
     1692                      sock)); 
     1693 
     1694            /* Create new accept_opt */ 
     1695            pool = pjsip_endpt_create_pool(listener->endpt, "tlss%p",  
     1696                                           POOL_TP_INIT, POOL_TP_INC); 
     1697            new_op = pj_pool_zalloc(pool, sizeof(struct pending_accept)); 
     1698            new_op->pool = pool; 
     1699            new_op->listener = listener; 
     1700            new_op->index = accept_op->index; 
     1701            pj_ioqueue_op_key_init(&new_op->op_key, sizeof(new_op->op_key)); 
     1702            listener->accept_op[accept_op->index] = new_op; 
     1703 
     1704            /*  
     1705             * Incoming connections! 
     1706             * Create TLS transport for the new socket. 
     1707             */ 
     1708            status = tls_create( listener, accept_op->pool, sock, PJ_TRUE, 
     1709                                 &accept_op->local_addr,  
     1710                                 &accept_op->remote_addr, &tls); 
     1711            if (status == PJ_SUCCESS) { 
     1712                /* Complete SSL_accept() */ 
     1713                status = ssl_accept(tls); 
     1714            } 
     1715 
     1716            if (status == PJ_SUCCESS) { 
     1717                /* Start asynchronous read from the socket */ 
     1718                status = tls_start_read(tls); 
     1719            } 
     1720 
     1721            if (status != PJ_SUCCESS) { 
     1722                ssl_report_error(tls->base.obj_name, 4, status, 
     1723                                 "Error creating incoming TLS transport"); 
     1724                pjsip_transport_shutdown(&tls->base); 
     1725            } 
     1726 
     1727            accept_op = new_op; 
     1728        } 
     1729 
     1730next_accept: 
     1731        /* 
     1732         * Start the next asynchronous accept() operation. 
     1733         */ 
     1734        accept_op->addr_len = sizeof(pj_sockaddr_in); 
     1735        accept_op->new_sock = PJ_INVALID_SOCKET; 
     1736 
     1737        status = pj_ioqueue_accept(listener->key,  
     1738                                   &accept_op->op_key, 
     1739                                   &accept_op->new_sock, 
     1740                                   &accept_op->local_addr, 
     1741                                   &accept_op->remote_addr, 
     1742                                   &accept_op->addr_len); 
     1743 
     1744        /* 
     1745         * Loop while we have immediate connection or when there is error. 
     1746         */ 
     1747 
     1748    } while (status != PJ_EPENDING); 
     1749} 
     1750 
     1751 
     1752/*  
     1753 * Callback from ioqueue when packet is sent. 
     1754 */ 
     1755static void on_write_complete(pj_ioqueue_key_t *key,  
     1756                              pj_ioqueue_op_key_t *op_key,  
     1757                              pj_ssize_t bytes_sent) 
     1758{ 
     1759    struct tls_transport *tls = pj_ioqueue_get_user_data(key); 
     1760    pjsip_tx_data_op_key *tdata_op_key = (pjsip_tx_data_op_key*)op_key; 
     1761 
     1762    tdata_op_key->tdata = NULL; 
     1763 
     1764    /* Check for error/closure */ 
     1765    if (bytes_sent <= 0) { 
     1766        pj_status_t status; 
     1767 
     1768        ssl_report_error(tls->base.obj_name, 4, -bytes_sent,  
     1769                         "TLS send() error"); 
     1770 
     1771        status = (bytes_sent == 0) ? PJ_STATUS_FROM_OS(OSERR_ENOTCONN) : 
     1772                                     -bytes_sent; 
     1773        if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 
     1774        pjsip_transport_shutdown(&tls->base); 
     1775    } 
     1776 
     1777    if (tdata_op_key->callback) { 
     1778        /* 
     1779         * Notify sip_transport.c that packet has been sent. 
     1780         */ 
     1781        tdata_op_key->callback(&tls->base, tdata_op_key->token, bytes_sent); 
     1782    } 
     1783} 
     1784 
     1785 
     1786/* Add tdata to pending list */ 
     1787static void add_pending_tx(struct tls_transport *tls, 
     1788                           pjsip_tx_data *tdata) 
     1789{ 
     1790    struct delayed_tdata *delayed_tdata; 
     1791 
     1792    delayed_tdata = pj_pool_alloc(tdata->pool,  
     1793                                  sizeof(*delayed_tdata)); 
     1794    delayed_tdata->tdata_op_key = &tdata->op_key; 
     1795    pj_list_push_back(&tls->delayed_list, delayed_tdata); 
     1796} 
     1797 
     1798 
     1799/*  
     1800 * This callback is called by transport manager to send SIP message  
     1801 */ 
     1802static pj_status_t tls_send_msg(pjsip_transport *transport,  
     1803                                pjsip_tx_data *tdata, 
     1804                                const pj_sockaddr_t *rem_addr, 
     1805                                int addr_len, 
     1806                                void *token, 
     1807                                void (*callback)(pjsip_transport *transport, 
     1808                                                 void *token,  
     1809                                                 pj_ssize_t sent_bytes)) 
     1810{ 
     1811    struct tls_transport *tls = (struct tls_transport*)transport; 
     1812    pj_ssize_t size; 
     1813    pj_bool_t delayed = PJ_FALSE; 
     1814    pj_status_t status = PJ_SUCCESS; 
     1815 
     1816    /* Sanity check */ 
     1817    PJ_ASSERT_RETURN(transport && tdata, PJ_EINVAL); 
     1818 
     1819    /* Check that there's no pending operation associated with the tdata */ 
     1820    PJ_ASSERT_RETURN(tdata->op_key.tdata == NULL, PJSIP_EPENDINGTX); 
     1821     
     1822    /* Check the address is supported */ 
     1823    PJ_ASSERT_RETURN(rem_addr && addr_len==sizeof(pj_sockaddr_in), PJ_EINVAL); 
     1824 
     1825 
     1826 
     1827    /* Init op key. */ 
     1828    tdata->op_key.tdata = tdata; 
     1829    tdata->op_key.token = token; 
     1830    tdata->op_key.callback = callback; 
     1831 
     1832    /* If asynchronous connect() has not completed yet, just put the 
     1833     * transmit data in the pending transmission list since we can not 
     1834     * use the socket yet. 
     1835     */ 
     1836    if (tls->has_pending_connect) { 
     1837 
     1838        /* 
     1839         * Looks like connect() is still in progress. Check again (this time 
     1840         * with holding the lock) to be sure. 
     1841         */ 
     1842        pj_lock_acquire(tls->base.lock); 
     1843 
     1844        if (tls->has_pending_connect) { 
     1845            /* 
     1846             * connect() is still in progress. Put the transmit data to 
     1847             * the delayed list. 
     1848             */ 
     1849            add_pending_tx(tls, tdata); 
     1850            status = PJ_EPENDING; 
     1851 
     1852            /* Prevent ssl_write() to be called below */ 
     1853            delayed = PJ_TRUE; 
     1854        } 
     1855 
     1856        pj_lock_release(tls->base.lock); 
     1857    }  
     1858     
     1859    if (!delayed) { 
     1860 
     1861        pj_bool_t no_pending_tx; 
     1862 
     1863        /* Make sure that we've flushed pending tx first so that 
     1864         * stream is in order. 
     1865         */ 
     1866        no_pending_tx = tls_flush_pending_tx(tls); 
     1867 
     1868        /* Send data immediately with SSL_write() if we don't have 
     1869         * pending data in our list. 
     1870         */ 
     1871        if (no_pending_tx) { 
     1872 
     1873            status = ssl_write(tls, tdata); 
     1874 
     1875            /* On EWOULDBLOCK, put this tdata in the list */ 
     1876            if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) { 
     1877                add_pending_tx(tls, tdata); 
     1878                status = PJ_EPENDING; 
     1879            } 
     1880 
     1881            if (status != PJ_EPENDING) { 
     1882                /* Not pending (could be immediate success or error) */ 
     1883                tdata->op_key.tdata = NULL; 
     1884 
     1885                /* Shutdown transport on closure/errors */ 
     1886                if (status != PJ_SUCCESS) { 
     1887                    size = -status; 
     1888 
     1889                    ssl_report_error(tls->base.obj_name, 4, status, 
     1890                                     "TLS send() error"); 
     1891 
     1892                    if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 
     1893                    pjsip_transport_shutdown(&tls->base); 
     1894                } 
     1895            } 
     1896 
     1897        } else { 
     1898            /* We have pending data in our list, so queue the txdata 
     1899             * in the pending tx list. 
     1900             */ 
     1901            add_pending_tx(tls, tdata); 
     1902            status = PJ_EPENDING; 
     1903        } 
     1904    } 
     1905 
     1906    return status; 
     1907} 
     1908 
     1909 
     1910/*  
     1911 * This callback is called by transport manager to shutdown transport. 
     1912 * This normally is only used by UDP transport. 
     1913 */ 
     1914static pj_status_t tls_shutdown(pjsip_transport *transport) 
     1915{ 
     1916    struct tls_transport *tls = (struct tls_transport*)transport; 
     1917 
     1918    /* Shutdown SSL */ 
     1919    if (!tls->ssl_shutdown_called) { 
     1920        /* Release our reference counter and shutdown SSL */ 
     1921        pjsip_transport_dec_ref(transport); 
     1922        SSL_shutdown(tls->ssl); 
     1923        tls->ssl_shutdown_called = PJ_TRUE; 
     1924 
     1925        PJ_LOG(4,(transport->obj_name, "TLS transport shutdown")); 
     1926    } 
    9351927 
    9361928    return PJ_SUCCESS; 
     
    9381930 
    9391931 
    940 /* 
    941  * Function to be called by transport manager to send SIP message. 
    942  */ 
    943 static pj_status_t tls_tp_send_msg(pjsip_transport *transport,  
    944                                    pjsip_tx_data *tdata, 
    945                                    const pj_sockaddr_t *rem_addr, 
    946                                    int addr_len, 
    947                                    void *token, 
    948                                    void (*callback)(pjsip_transport *transport, 
    949                                                     void *token,  
    950                                                     pj_ssize_t sent_bytes)) 
    951 { 
    952     struct tls_transport *tls_tp = (struct tls_transport*) transport; 
    953     int bytes_sent; 
    954  
    955     /* This is a connection oriented protocol, so rem_addr is not used */ 
    956     PJ_UNUSED_ARG(rem_addr); 
    957     PJ_UNUSED_ARG(addr_len); 
    958  
    959     /* Data written immediately, no need to call callback */ 
    960     PJ_UNUSED_ARG(callback); 
    961     PJ_UNUSED_ARG(token); 
    962  
    963     /* Write to TLS */ 
    964     bytes_sent = SSL_write (tls_tp->ssl, tdata->buf.start, 
    965                             tdata->buf.cur - tdata->buf.start); 
    966      
    967     switch (SSL_get_error (tls_tp->ssl, bytes_sent)) { 
    968     case SSL_ERROR_NONE: 
    969         pj_assert(bytes_sent == tdata->buf.cur - tdata->buf.start); 
    970         return PJ_SUCCESS; 
    971          
    972     case SSL_ERROR_WANT_READ: 
    973     case SSL_ERROR_WANT_WRITE: 
    974         return PJ_RETURN_OS_ERROR(OSERR_EWOULDBLOCK); 
    975          
    976     case SSL_ERROR_ZERO_RETURN: 
    977         /* The peer has notified us that it is shutting down via the SSL 
    978          * "close_notify" message so we need to shutdown, too. 
     1932/*  
     1933 * Callback from ioqueue that an incoming data is received from the socket. 
     1934 */ 
     1935static void on_read_complete(pj_ioqueue_key_t *key,  
     1936                             pj_ioqueue_op_key_t *op_key,  
     1937                             pj_ssize_t bytes_read_unused) 
     1938{ 
     1939    enum { MAX_IMMEDIATE_PACKET = 10 }; 
     1940    pjsip_rx_data_op_key *rdata_op_key = (pjsip_rx_data_op_key*) op_key; 
     1941    pjsip_rx_data *rdata = rdata_op_key->rdata; 
     1942    struct tls_transport *tls =  
     1943        (struct tls_transport*)rdata->tp_info.transport; 
     1944    int i; 
     1945    pj_status_t status; 
     1946 
     1947    /* Don't do anything if transport is closing. */ 
     1948    if (tls->is_closing) { 
     1949        tls->is_closing++; 
     1950        return; 
     1951    } 
     1952 
     1953 
     1954    /* Recall that we use MSG_PEEK when calling ioqueue_recv(), so 
     1955     * when this callback is called, data has not actually been read 
     1956     * from socket buffer. 
     1957     */ 
     1958 
     1959    for (i=0;; ++i) { 
     1960        pj_uint32_t flags; 
     1961 
     1962        /* Read data from SSL connection */ 
     1963        status = ssl_read(tls); 
     1964 
     1965        if (status == PJ_SUCCESS) { 
     1966            /* 
     1967             * We have packet! 
     1968             */ 
     1969            pj_size_t size_eaten; 
     1970 
     1971            /* Init pkt_info part. */ 
     1972            rdata->pkt_info.zero = 0; 
     1973            pj_gettimeofday(&rdata->pkt_info.timestamp); 
     1974 
     1975            /* Report to transport manager. 
     1976             * The transport manager will tell us how many bytes of the packet 
     1977             * have been processed (as valid SIP message). 
     1978             */ 
     1979            size_eaten =  
     1980                pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr,  
     1981                                           rdata); 
     1982 
     1983            pj_assert(size_eaten <= (pj_size_t)rdata->pkt_info.len); 
     1984 
     1985            /* Move unprocessed data to the front of the buffer */ 
     1986            if (size_eaten>0 && size_eaten<(pj_size_t)rdata->pkt_info.len) { 
     1987                pj_memmove(rdata->pkt_info.packet, 
     1988                           rdata->pkt_info.packet + size_eaten, 
     1989                           rdata->pkt_info.len - size_eaten); 
     1990            } 
     1991             
     1992            rdata->pkt_info.len -= size_eaten; 
     1993 
     1994        } else if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) { 
     1995 
     1996            /* Ignore EWOULDBLOCK error (?) */ 
     1997 
     1998        } else { 
     1999 
     2000            /* For other errors, treat as transport being closed */ 
     2001            ssl_report_error(tls->base.obj_name, 4, status, 
     2002                             "Error reading SSL stream"); 
     2003             
     2004            /* We can not destroy the transport since high level objects may 
     2005             * still keep reference to this transport. So we can only  
     2006             * instruct transport manager to gracefully start the shutdown 
     2007             * procedure for this transport. 
     2008             */ 
     2009            if (tls->close_reason==PJ_SUCCESS)  
     2010                tls->close_reason = status; 
     2011            pjsip_transport_shutdown(&tls->base); 
     2012 
     2013            return; 
     2014        } 
     2015 
     2016        /* Reset pool. */ 
     2017        pj_pool_reset(rdata->tp_info.pool); 
     2018 
     2019        /* If we have pending data in SSL buffer, read it. */ 
     2020        if (SSL_pending(tls->ssl)) { 
     2021 
     2022            /* Check that we have enough space in buffer */ 
     2023            if (rdata->pkt_info.len >= PJSIP_MAX_PKT_LEN-1) { 
     2024                PJ_LOG(4,(tls->base.obj_name,  
     2025                          "Incoming packet dropped from tls:%.*s:%d " 
     2026                          "because it's too big (%d bytes)", 
     2027                          (int)tls->base.remote_name.host.slen, 
     2028                          tls->base.remote_name.host.ptr, 
     2029                          tls->base.remote_name.port, 
     2030                          rdata->pkt_info.len)); 
     2031                rdata->pkt_info.len = 0; 
     2032            } 
     2033 
     2034            continue; 
     2035        } 
     2036 
     2037        /* If we've reached maximum number of packets received on a single 
     2038         * poll, force the next reading to be asynchronous. 
    9792039         */ 
    980         pj_assert(bytes_sent == tdata->buf.cur - tdata->buf.start); 
    981         SSL_shutdown (tls_tp->ssl); 
    982         pjsip_transport_shutdown(transport); 
    983         return PJ_SUCCESS; 
    984          
    985     case SSL_ERROR_SYSCALL: 
    986         if (bytes_sent == 0) { 
    987             /* An EOF occured but the SSL "close_notify" message was not 
    988              * sent.  This is a protocol error, but we ignore it. 
     2040        if (i >= MAX_IMMEDIATE_PACKET) { 
     2041            /* Receive quota reached. Force ioqueue_recv() to  
     2042             * return PJ_EPENDING  
    9892043             */ 
    990             pjsip_transport_shutdown(transport); 
    991             return 0; 
    992         } 
    993         return pj_get_netos_error(); 
    994          
    995     default: 
    996         /* Reset errno to prevent previous values (e.g. EWOULDBLOCK) 
    997          * from being associated with fatal SSL errors. 
     2044            flags = PJ_IOQUEUE_ALWAYS_ASYNC; 
     2045        } else { 
     2046            flags = 0; 
     2047        } 
     2048 
     2049        /* Read next packet from the network. Remember, we need to use 
     2050         * MSG_PEEK or otherwise the packet will be eaten by us! 
    9982051         */ 
    999         pj_set_netos_error(0); 
    1000         ssl_report_error(4, transport->obj_name, "SSL_write error"); 
    1001         return PJSIP_TLS_ESEND; 
    1002     } 
    1003 } 
    1004  
    1005  
    1006 /* 
    1007  * Instruct the transport to initiate graceful shutdown procedure. 
    1008  */ 
    1009 static pj_status_t tls_tp_do_shutdown(pjsip_transport *transport) 
    1010 { 
    1011     PJ_LOG(4,(transport->obj_name, "TLS transport marked for shutdown..")); 
    1012  
    1013     /* Nothing to do for TLS */ 
    1014     PJ_UNUSED_ARG(transport); 
    1015  
    1016     return PJ_SUCCESS; 
    1017 } 
    1018  
    1019 /* 
    1020  * Forcefully destroy this transport. 
    1021  */ 
    1022 static pj_status_t tls_tp_destroy(pjsip_transport *transport) 
    1023 { 
    1024     struct tls_transport *tls_tp = (struct tls_transport*) transport; 
    1025  
    1026     PJ_LOG(4,(transport->obj_name, "Destroying TLS transport..")); 
    1027  
    1028     if (tls_tp->thread) { 
    1029         tls_tp->quitting = PJ_TRUE; 
    1030         SSL_shutdown(tls_tp->ssl); 
    1031  
    1032         pj_thread_join(tls_tp->thread); 
    1033         pj_thread_destroy(tls_tp->thread); 
    1034         tls_tp->thread = NULL; 
    1035     } 
    1036  
    1037     if (tls_tp->ssl) { 
    1038         int rc; 
    1039         rc = SSL_shutdown(tls_tp->ssl); 
    1040         if (rc == 0) { 
    1041             pj_sock_shutdown(tls_tp->sock, PJ_SD_BOTH); 
    1042             SSL_shutdown(tls_tp->ssl); 
    1043         } 
    1044  
    1045         SSL_free(tls_tp->ssl); 
    1046         tls_tp->ssl = NULL; 
    1047         tls_tp->sock = PJ_INVALID_SOCKET; 
    1048  
    1049     } else if (tls_tp->sock != PJ_INVALID_SOCKET) { 
    1050         pj_sock_close(tls_tp->sock); 
    1051         tls_tp->sock = PJ_INVALID_SOCKET; 
    1052     } 
    1053  
    1054     if (tls_tp->base.lock) { 
    1055         pj_lock_destroy(tls_tp->base.lock); 
    1056         tls_tp->base.lock = NULL; 
    1057     } 
    1058  
    1059     if (tls_tp->base.ref_cnt) { 
    1060         pj_atomic_destroy(tls_tp->base.ref_cnt); 
    1061         tls_tp->base.ref_cnt = NULL; 
    1062     } 
    1063  
    1064     if (tls_tp->base.pool) { 
    1065         pj_pool_t *pool = tls_tp->base.pool; 
    1066         tls_tp->base.pool = NULL; 
    1067         pj_pool_release(pool); 
    1068     } 
    1069  
    1070     PJ_LOG(4,(THIS_FILE, "TLS transport destroyed")); 
    1071     return PJ_SUCCESS; 
    1072 } 
    1073  
     2052        bytes_read_unused = 1; 
     2053        status = pj_ioqueue_recv(key, op_key,  
     2054                                 rdata->pkt_info.packet+rdata->pkt_info.len, 
     2055                                 &bytes_read_unused, flags | PJ_MSG_PEEK); 
     2056 
     2057        if (status == PJ_SUCCESS) { 
     2058 
     2059            /* Continue loop. */ 
     2060            pj_assert(i < MAX_IMMEDIATE_PACKET); 
     2061 
     2062        } else if (status == PJ_EPENDING) { 
     2063            break; 
     2064 
     2065        } else { 
     2066            /* Socket error */ 
     2067 
     2068            /* We can not destroy the transport since high level objects may 
     2069             * still keep reference to this transport. So we can only  
     2070             * instruct transport manager to gracefully start the shutdown 
     2071             * procedure for this transport. 
     2072             */ 
     2073            if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 
     2074            pjsip_transport_shutdown(&tls->base); 
     2075 
     2076            return; 
     2077        } 
     2078    } 
     2079} 
     2080 
     2081 
     2082/*  
     2083 * Callback from ioqueue when asynchronous connect() operation completes. 
     2084 */ 
     2085static void on_connect_complete(pj_ioqueue_key_t *key,  
     2086                                pj_status_t status) 
     2087{ 
     2088    struct tls_transport *tls; 
     2089    pj_sockaddr_in addr; 
     2090    int addrlen; 
     2091 
     2092    tls = pj_ioqueue_get_user_data(key); 
     2093 
     2094    /* Check connect() status */ 
     2095    if (status != PJ_SUCCESS) { 
     2096 
     2097        /* Mark that pending connect() operation has completed. */ 
     2098        tls->has_pending_connect = PJ_FALSE; 
     2099 
     2100        ssl_report_error(tls->base.obj_name, 4, status, 
     2101                         "Error connecting to %.*s:%d", 
     2102                         (int)tls->base.remote_name.host.slen, 
     2103                         tls->base.remote_name.host.ptr, 
     2104                         tls->base.remote_name.port); 
     2105 
     2106        /* Cancel all delayed transmits */ 
     2107        while (!pj_list_empty(&tls->delayed_list)) { 
     2108            struct delayed_tdata *pending_tx; 
     2109            pj_ioqueue_op_key_t *op_key; 
     2110 
     2111            pending_tx = tls->delayed_list.next; 
     2112            pj_list_erase(pending_tx); 
     2113 
     2114            op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key; 
     2115 
     2116            on_write_complete(tls->key, op_key, -status); 
     2117        } 
     2118 
     2119        /* We can not destroy the transport since high level objects may 
     2120         * still keep reference to this transport. So we can only  
     2121         * instruct transport manager to gracefully start the shutdown 
     2122         * procedure for this transport. 
     2123         */ 
     2124        if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 
     2125        pjsip_transport_shutdown(&tls->base); 
     2126        return; 
     2127    } 
     2128 
     2129    PJ_LOG(4,(tls->base.obj_name,  
     2130              "TCP transport %.*s:%d is connected to %.*s:%d", 
     2131              (int)tls->base.local_name.host.slen, 
     2132              tls->base.local_name.host.ptr, 
     2133              tls->base.local_name.port, 
     2134              (int)tls->base.remote_name.host.slen, 
     2135              tls->base.remote_name.host.ptr, 
     2136              tls->base.remote_name.port)); 
     2137 
     2138 
     2139    /* Update (again) local address, just in case local address currently 
     2140     * set is different now that the socket is connected (could happen 
     2141     * on some systems, like old Win32 probably?). 
     2142     */ 
     2143    addrlen = sizeof(pj_sockaddr_in); 
     2144    if (pj_sock_getsockname(tls->sock, &addr, &addrlen)==PJ_SUCCESS) { 
     2145        pj_sockaddr_in *tp_addr = (pj_sockaddr_in*)&tls->base.local_addr; 
     2146 
     2147        if (tp_addr->sin_addr.s_addr != addr.sin_addr.s_addr) { 
     2148            tp_addr->sin_addr.s_addr = addr.sin_addr.s_addr; 
     2149            tp_addr->sin_port = addr.sin_port; 
     2150            sockaddr_to_host_port(tls->base.pool, &tls->base.local_name, 
     2151                                  tp_addr); 
     2152        } 
     2153    } 
     2154 
     2155    /* Perform SSL_connect() */ 
     2156    status = ssl_connect(tls); 
     2157    if (status != PJ_SUCCESS) { 
     2158 
     2159        /* Cancel all delayed transmits */ 
     2160        while (!pj_list_empty(&tls->delayed_list)) { 
     2161            struct delayed_tdata *pending_tx; 
     2162            pj_ioqueue_op_key_t *op_key; 
     2163 
     2164            pending_tx = tls->delayed_list.next; 
     2165            pj_list_erase(pending_tx); 
     2166 
     2167            op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key; 
     2168 
     2169            on_write_complete(tls->key, op_key, -status); 
     2170        } 
     2171 
     2172        if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 
     2173        pjsip_transport_shutdown(&tls->base); 
     2174        return; 
     2175    } 
     2176 
     2177    /* Mark that pending connect() operation has completed. */ 
     2178    tls->has_pending_connect = PJ_FALSE; 
     2179 
     2180    /* Start pending read */ 
     2181    status = tls_start_read(tls); 
     2182    if (status != PJ_SUCCESS) { 
     2183 
     2184        /* Cancel all delayed transmits */ 
     2185        while (!pj_list_empty(&tls->delayed_list)) { 
     2186            struct delayed_tdata *pending_tx; 
     2187            pj_ioqueue_op_key_t *op_key; 
     2188 
     2189            pending_tx = tls->delayed_list.next; 
     2190            pj_list_erase(pending_tx); 
     2191 
     2192            op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key; 
     2193 
     2194            on_write_complete(tls->key, op_key, -status); 
     2195        } 
     2196 
     2197 
     2198        /* We can not destroy the transport since high level objects may 
     2199         * still keep reference to this transport. So we can only  
     2200         * instruct transport manager to gracefully start the shutdown 
     2201         * procedure for this transport. 
     2202         */ 
     2203        if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 
     2204        pjsip_transport_shutdown(&tls->base); 
     2205        return; 
     2206    } 
     2207 
     2208    /* Flush all pending send operations */ 
     2209    tls_flush_pending_tx(tls); 
     2210} 
    10742211 
    10752212#endif  /* PJSIP_HAS_TLS_TRANSPORT */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r849 r861  
    10501050         * Create TLS transport. 
    10511051         */ 
     1052        /* 
     1053         * Create TCP transport. 
     1054         */ 
     1055        pjsua_transport_config config; 
     1056        pjsip_host_port a_name; 
    10521057        pjsip_tpfactory *tls; 
     1058        pj_sockaddr_in local_addr; 
     1059 
     1060        /* Supply default config if it's not specified */ 
     1061        if (cfg == NULL) { 
     1062            pjsua_transport_config_default(&config); 
     1063            config.port = 5061; 
     1064            cfg = &config; 
     1065        } 
     1066 
     1067        /* Init local address */ 
     1068        pj_sockaddr_in_init(&local_addr, 0, 0); 
     1069 
     1070        if (cfg->port) 
     1071            local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port); 
     1072 
     1073        if (cfg->bound_addr.slen) { 
     1074            status = pj_sockaddr_in_set_str_addr(&local_addr,&cfg->bound_addr); 
     1075            if (status != PJ_SUCCESS) { 
     1076                pjsua_perror(THIS_FILE,  
     1077                             "Unable to resolve transport bound address",  
     1078                             status); 
     1079                goto on_return; 
     1080            } 
     1081        } 
     1082 
     1083        /* Init published name */ 
     1084        pj_bzero(&a_name, sizeof(pjsip_host_port)); 
     1085        if (cfg->public_addr.slen) 
     1086            a_name.host = cfg->public_addr; 
    10531087 
    10541088        status = pjsip_tls_transport_start(pjsua_var.endpt,  
    1055                                            &cfg->tls_key_file, 
    1056                                            &cfg->tls_password,  
    1057                                            &cfg->tls_ca_file, 
    1058                                            NULL, NULL, 1, &tls); 
     1089                                           &cfg->tls_setting,  
     1090                                           &local_addr, &a_name, 1, &tls); 
    10591091        if (status != PJ_SUCCESS) { 
    10601092            pjsua_perror(THIS_FILE, "Error creating SIP TLS listener",  
Note: See TracChangeset for help on using the changeset viewer.