source: sources/src/ioNetworkSslClient.cc @ 1464:3f6711617be1

Revision 1464:3f6711617be1, 19.8 KB checked in by niam, 22 months ago (diff)

{issue #58[resolved]} support for non-c++ exceptions

Line 
1/***************************************************************************
2 *            ioNetworkSslClient.cc
3 *
4 *  Tue Jun 10 2008
5 *  Copyright  2008  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef OPENSSL_EXT
33#include <sys/socket.h>
34#include <sys/un.h>
35#include <arpa/inet.h>
36#include <netinet/in.h>
37#include <openssl/ssl.h>
38#include <openssl/err.h>
39#include <unistd.h>
40
41#include "ioSsl.inline"
42
43#include <libdodo/ioNetworkSslClient.h>
44#include <libdodo/toolsFilesystem.h>
45#include <libdodo/ioNetworkSslClientEx.h>
46#include <libdodo/ioSsl.h>
47#include <libdodo/types.h>
48#include <libdodo/ioNetworkSslExchange.h>
49#include <libdodo/xexec.h>
50
51using namespace dodo::io::network::ssl;
52
53client::client(client &fs) : network::client(fs)
54{
55}
56
57//-------------------------------------------------------------------
58
59client::client(short a_family,
60               short a_type) : network::client(a_family,
61                                               a_type),
62                               handle(new io::ssl::__connection__),
63                               ctx(new io::ssl::__context__),
64                               sslConnected(false)
65{
66#ifndef IO_WO_XEXEC
67    collectedData.setExecObject(xexec::OBJECT_IONETWORKSSLCLIENT);
68#endif
69
70    ctx->ctx = NULL;
71    handle->handle = NULL;
72}
73
74//-------------------------------------------------------------------
75
76client::~client()
77{
78    if (handle->handle != NULL) {
79        if (sslConnected && SSL_shutdown(handle->handle) == 0)
80            SSL_shutdown(handle->handle);
81
82        SSL_free(handle->handle);
83    }
84
85    if (ctx->ctx != NULL)
86        SSL_CTX_free(ctx->ctx);
87
88    delete handle;
89    delete ctx;
90}
91
92//-------------------------------------------------------------------
93
94void
95client::removeSertificates()
96{
97    if (handle->handle != NULL) {
98        if (sslConnected) {
99            int err = SSL_shutdown(handle->handle);
100            if (err < 0) {
101                unsigned long nerr = ERR_get_error();
102                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_REMOVESERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
103            }
104            if (err == 0) {
105                err = SSL_shutdown(handle->handle);
106                if (err < 0) {
107                    unsigned long nerr = ERR_get_error();
108                    dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_REMOVESERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
109                }
110            }
111
112            sslConnected = false;
113        }
114
115        SSL_free(handle->handle);
116
117        handle->handle = NULL;
118    }
119
120    if (ctx->ctx != NULL) {
121        SSL_CTX_free(ctx->ctx);
122
123        ctx->ctx = NULL;
124    }
125
126    ctx->ctx = SSL_CTX_new(SSLv23_client_method());
127    if (ctx->ctx == NULL)
128        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_REMOVESERTIFICATES, exception::ERRNO_LIBDODO, CLIENTEX_UNABLETOINITCONTEXT, IONETWORKSSLCLIENTEX_UNABLETOINITCONTEXT_STR, __LINE__, __FILE__);
129
130    handle->handle = SSL_new(ctx->ctx);
131    if (handle->handle == NULL)
132        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_REMOVESERTIFICATES, exception::ERRNO_LIBDODO, CLIENTEX_UNABLETOINITSSL, IONETWORKSSLCLIENTEX_UNABLETOINITSSL_STR, __LINE__, __FILE__);
133}
134
135//-------------------------------------------------------------------
136
137void
138client::setSertificates(const io::ssl::__certificates__ &certs)
139{
140    if (handle->handle != NULL) {
141        if (sslConnected) {
142            int err = SSL_shutdown(handle->handle);
143            if (err < 0) {
144                unsigned long nerr = ERR_get_error();
145                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
146            }
147            if (err == 0) {
148                err = SSL_shutdown(handle->handle);
149                if (err < 0) {
150                    unsigned long nerr = ERR_get_error();
151                    dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
152                }
153            }
154
155            sslConnected = false;
156        }
157
158        SSL_free(handle->handle);
159
160        handle->handle = NULL;
161    }
162
163    if (ctx->ctx != NULL) {
164        SSL_CTX_free(ctx->ctx);
165
166        ctx->ctx = NULL;
167    }
168
169    ctx->ctx = SSL_CTX_new(SSLv23_client_method());
170    if (ctx->ctx == NULL)
171        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_LIBDODO, CLIENTEX_UNABLETOINITCONTEXT, IONETWORKSSLCLIENTEX_UNABLETOINITCONTEXT_STR, __LINE__, __FILE__);
172
173    if (certs.cipher.size() > 0 && SSL_CTX_set_cipher_list(ctx->ctx, certs.cipher.data()) != 1) {
174        unsigned long nerr = ERR_get_error();
175        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
176    }
177
178    if (certs.ca.size() > 0 && SSL_CTX_use_certificate_chain_file(ctx->ctx, certs.ca.data()) != 1) {
179        unsigned long nerr = ERR_get_error();
180        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
181    }
182
183    if (certs.cert.size() > 0 && SSL_CTX_use_certificate_file(ctx->ctx, certs.cert.data(), SSL_FILETYPE_PEM) != 1) {
184        unsigned long nerr = ERR_get_error();
185        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
186    }
187
188    if (certs.keyPassword.size() > 0)
189        SSL_CTX_set_default_passwd_cb_userdata(ctx->ctx, (void *)certs.keyPassword.data());
190
191    bool keySet = false;
192
193    if (certs.key.size() > 0) {
194        switch (certs.keyType) {
195            case io::ssl::KEY_PKEY:
196
197                if (SSL_CTX_use_PrivateKey_file(ctx->ctx, certs.key.data(), SSL_FILETYPE_PEM) != 1) {
198                    unsigned long nerr = ERR_get_error();
199                    dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
200                }
201
202                keySet = true;
203
204                break;
205
206            case io::ssl::KEY_RSA:
207
208                if (SSL_CTX_use_RSAPrivateKey_file(ctx->ctx, certs.key.data(), SSL_FILETYPE_PEM) != 1) {
209                    unsigned long nerr = ERR_get_error();
210                    dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
211                }
212
213                keySet = true;
214
215                break;
216
217            default:
218
219                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_LIBDODO, CLIENTEX_UNKNOWNKEYTYPE, IONETWORKSSLCLIENTEX_UNKNOWNKEY_STR, __LINE__, __FILE__);
220        }
221    } else {
222        if (certs.ca.size() > 0) {
223            if (SSL_CTX_use_PrivateKey_file(ctx->ctx, certs.ca.data(), SSL_FILETYPE_PEM) != 1) {
224                unsigned long nerr = ERR_get_error();
225                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
226            }
227
228            keySet = true;
229        }
230    }
231
232    if (certs.caPath.size() > 0) {
233        if (tools::filesystem::file(certs.caPath).type == tools::filesystem::FILE_DIRECTORY) {
234            if (SSL_CTX_load_verify_locations(ctx->ctx, NULL, certs.caPath.data()) != 1) {
235                unsigned long nerr = ERR_get_error();
236                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
237            }
238        } else {
239            if (SSL_CTX_load_verify_locations(ctx->ctx, certs.caPath.data(), NULL) != 1) {
240                unsigned long nerr = ERR_get_error();
241                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
242            }
243        }
244    }
245
246    if (keySet && SSL_CTX_check_private_key(ctx->ctx) != 1) {
247        unsigned long nerr = ERR_get_error();
248        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
249    }
250
251    handle->handle = SSL_new(ctx->ctx);
252    if (handle->handle == NULL)
253        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_SETSERTIFICATES, exception::ERRNO_LIBDODO, CLIENTEX_UNABLETOINITSSL, IONETWORKSSLCLIENTEX_UNABLETOINITSSL_STR, __LINE__, __FILE__);
254}
255
256//-------------------------------------------------------------------
257
258void
259client::initSsl()
260{
261    if (ctx->ctx == NULL) {
262        ctx->ctx = SSL_CTX_new(SSLv23_client_method());
263        if (ctx->ctx == NULL)
264            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_INITSSL, exception::ERRNO_LIBDODO, CLIENTEX_UNABLETOINITCONTEXT, IONETWORKSSLCLIENTEX_UNABLETOINITCONTEXT_STR, __LINE__, __FILE__);
265    }
266
267    if (handle->handle == NULL) {
268        handle->handle = SSL_new(ctx->ctx);
269        if (handle->handle == NULL)
270            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_INITSSL, exception::ERRNO_LIBDODO, CLIENTEX_UNABLETOINITSSL, IONETWORKSSLCLIENTEX_UNABLETOINITSSL_STR, __LINE__, __FILE__);
271    }
272}
273
274//-------------------------------------------------------------------
275
276void
277client::connectSsl()
278{
279    io::ssl::__openssl___init_object__.addEntropy();
280
281    if (sslConnected) {
282        int err = SSL_shutdown(handle->handle);
283        if (err < 0) {
284            unsigned long nerr = ERR_get_error();
285            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
286        }
287        if (err == 0) {
288            err = SSL_shutdown(handle->handle);
289            if (err < 0) {
290                unsigned long nerr = ERR_get_error();
291                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
292            }
293        }
294
295        sslConnected = false;
296    }
297
298    if (SSL_clear(handle->handle) == 0) {
299        unsigned long nerr = ERR_get_error();
300        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
301    }
302
303    if (SSL_set_fd(handle->handle, socket) == 0) {
304        unsigned long nerr = ERR_get_error();
305        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
306    }
307
308    int res = SSL_connect(handle->handle);
309    switch (res) {
310        case 1:
311            break;
312
313        case 0:
314        {
315            unsigned long nerr = ERR_get_error();
316            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
317        }
318
319        case - 1:
320        {
321            int nerr = SSL_get_error(handle->handle, res);
322            if (nerr == SSL_ERROR_WANT_READ || nerr == SSL_ERROR_WANT_WRITE || nerr == SSL_ERROR_WANT_X509_LOOKUP)
323                break;
324        }
325
326        default:
327        {
328            unsigned long nerr = ERR_get_error();
329
330            int err = SSL_shutdown(handle->handle);
331            if (err < 0) {
332                nerr = ERR_get_error();
333                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
334            }
335            if (err == 0) {
336                err = SSL_shutdown(handle->handle);
337                if (err < 0) {
338                    nerr = ERR_get_error();
339                    dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
340                }
341            }
342
343            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTSSL, exception::ERRNO_OPENSSL, nerr, ERR_error_string(nerr, NULL), __LINE__, __FILE__);
344        }
345    }
346
347    sslConnected = true;
348}
349
350//-------------------------------------------------------------------
351
352void
353client::connect(const dodo::string  &host,
354                int               port,
355                network::exchange &ex)
356{
357#ifndef IO_WO_XEXEC
358    performPreExec(OPERATION_CONNECT);
359#endif
360
361    initSsl();
362    makeSocket();
363
364    if (family == PROTOCOL_FAMILY_IPV4) {
365        struct sockaddr_in sa;
366        sa.sin_family = AF_INET;
367        sa.sin_port = htons(port);
368        inet_aton(host.data(), &sa.sin_addr);
369
370        if (::connect(socket, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
371            if (::close(socket) == -1)
372                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
373
374            socket = -1;
375
376            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
377        }
378    } else {
379        struct sockaddr_in6 sa;
380        sa.sin6_family = AF_INET6;
381        sa.sin6_port = htons(port);
382        sa.sin6_flowinfo = 0;
383        sa.sin6_scope_id = 0;
384        inet_pton(AF_INET6, host.data(), &sa.sin6_addr);
385
386        if (::connect(socket, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
387            if (::close(socket) == -1)
388                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
389
390            socket = -1;
391
392            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
393        }
394    }
395
396    connectSsl();
397
398    exchange &sslEx = dynamic_cast<exchange &>(ex);
399    sslEx.init(socket, handle, blocked, blockInherited);
400
401    socket = -1;
402    handle->handle = NULL;
403
404#ifndef IO_WO_XEXEC
405    performPostExec(OPERATION_CONNECT);
406#endif
407}
408
409//-------------------------------------------------------------------
410
411void
412client::connectFrom(const dodo::string  &local,
413                    const dodo::string  &host,
414                    int               port,
415                    network::exchange &ex)
416{
417#ifndef IO_WO_XEXEC
418    performPreExec(OPERATION_CONNECTFROM);
419#endif
420
421    initSsl();
422    makeSocket();
423
424    int sockFlag(1);
425    if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &sockFlag, sizeof(int)) == -1)
426        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTFROM, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
427
428    addFlag(socketOpts, 1 << OPTION_REUSE_ADDRESS);
429
430    if (family == PROTOCOL_FAMILY_IPV4) {
431        struct sockaddr_in sa;
432        sa.sin_family = AF_INET;
433        sa.sin_port = htons(0);
434        inet_aton(local.data(), &sa.sin_addr);
435
436        if (::bind(socket, (struct sockaddr *)&sa, sizeof(sa)) == -1)
437            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTFROM, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
438
439        sa.sin_port = htons(port);
440        inet_aton(host.data(), &sa.sin_addr);
441
442        if (::connect(socket, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
443            if (::close(socket) == -1)
444                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTFROM, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
445
446            socket = -1;
447
448            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTFROM, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
449        }
450    } else {
451        struct sockaddr_in6 sa;
452        sa.sin6_family = AF_INET6;
453        sa.sin6_flowinfo = 0;
454        sa.sin6_scope_id = 0;
455        sa.sin6_port = htons(0);
456        inet_pton(AF_INET6, local.data(), &sa.sin6_addr);
457
458        if (::bind(socket, (struct sockaddr *)&sa, sizeof(sa)) == -1)
459            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTFROM, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
460
461        sa.sin6_port = htons(port);
462        inet_pton(AF_INET6, host.data(), &sa.sin6_addr);
463
464        if (::connect(socket, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
465            if (::close(socket) == -1)
466                dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTFROM, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
467
468            socket = -1;
469
470            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECTFROM, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
471        }
472    }
473
474    connectSsl();
475
476    exchange &sslEx = dynamic_cast<exchange &>(ex);
477    sslEx.init(socket, handle, blocked, blockInherited);
478
479    socket = -1;
480    handle->handle = NULL;
481
482#ifndef IO_WO_XEXEC
483    performPostExec(OPERATION_CONNECTFROM);
484#endif
485}
486
487//-------------------------------------------------------------------
488
489void
490client::connect(const dodo::string  &path,
491                network::exchange &ex)
492{
493#ifndef IO_WO_XEXEC
494    performPreExec(OPERATION_CONNECT);
495#endif
496
497    initSsl();
498    makeSocket();
499
500    struct sockaddr_un sa;
501
502    unsigned long size = path.size();
503
504    if (size >= 108)
505        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECT, exception::ERRNO_LIBDODO, CLIENTEX_LONGPATH, IONETWORKSSLCLIENTEX_LONGPATH_STR, __LINE__, __FILE__);
506
507    strncpy(sa.sun_path, path.data(), size);
508    sa.sun_family = AF_UNIX;
509
510    if (::connect(socket, (struct sockaddr *)&sa, path.size() + sizeof(sa.sun_family)) == -1) {
511        if (::close(socket) == -1)
512            dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
513
514        socket = -1;
515
516        dodo_throw exception::basic(exception::MODULE_IONETWORKSSLCLIENT, CLIENTEX_CONNECT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
517    }
518
519    connectSsl();
520
521    exchange &sslEx = dynamic_cast<exchange &>(ex);
522    sslEx.init(socket, handle, blocked, blockInherited);
523
524    socket = -1;
525    handle->handle = NULL;
526
527#ifndef IO_WO_XEXEC
528    performPostExec(OPERATION_CONNECT);
529#endif
530}
531
532//-------------------------------------------------------------------
533#endif
534
Note: See TracBrowser for help on using the repository browser.