| File: | libsofia-sip-ua/tport/tport_type_tls.c |
| Warning: | line 601, column 5 The left operand of '==' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * This file is part of the Sofia-SIP package | |||
| 3 | * | |||
| 4 | * Copyright (C) 2005 Nokia Corporation. | |||
| 5 | * | |||
| 6 | * Contact: Pekka Pessi <pekka.pessi@nokia.com> | |||
| 7 | * | |||
| 8 | * This library is free software; you can redistribute it and/or | |||
| 9 | * modify it under the terms of the GNU Lesser General Public License | |||
| 10 | * as published by the Free Software Foundation; either version 2.1 of | |||
| 11 | * the License, or (at your option) any later version. | |||
| 12 | * | |||
| 13 | * This library is distributed in the hope that it will be useful, but | |||
| 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 16 | * Lesser General Public License for more details. | |||
| 17 | * | |||
| 18 | * You should have received a copy of the GNU Lesser General Public | |||
| 19 | * License along with this library; if not, write to the Free Software | |||
| 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |||
| 21 | * 02110-1301 USA | |||
| 22 | * | |||
| 23 | */ | |||
| 24 | ||||
| 25 | /**@CFILE tport_type_tls.c TLS over TCP Transport | |||
| 26 | * | |||
| 27 | * See tport.docs for more detailed description of tport interface. | |||
| 28 | * | |||
| 29 | * @author Pekka Pessi <Pekka.Pessi@nokia.com> | |||
| 30 | * @author Ismo Puustinen <Ismo.H.Puustinen@nokia.com> | |||
| 31 | * @author Tat Chan <Tat.Chan@nokia.com> | |||
| 32 | * @author Kai Vehmanen <kai.vehmanen@nokia.com> | |||
| 33 | * @author Martti Mela <Martti.Mela@nokia.com> | |||
| 34 | * @author Jarod Neuner <janeuner@networkharbor.com> | |||
| 35 | * | |||
| 36 | * @date Split here: Fri Mar 24 08:45:49 EET 2006 ppessi | |||
| 37 | * @date Originally Created: Thu Jul 20 12:54:32 2000 ppessi | |||
| 38 | */ | |||
| 39 | ||||
| 40 | #include "config.h" | |||
| 41 | ||||
| 42 | #define SU_WAKEUP_ARG_Tstruct tport_s struct tport_s | |||
| 43 | ||||
| 44 | #include "tport_internal.h" | |||
| 45 | ||||
| 46 | #include <stdlib.h> | |||
| 47 | #include <time.h> | |||
| 48 | #include <assert.h> | |||
| 49 | #include <errno(*__errno_location ()).h> | |||
| 50 | #include <limits.h> | |||
| 51 | #include <string.h> | |||
| 52 | #include <sofia-sip/su_string.h> | |||
| 53 | ||||
| 54 | #if HAVE_FUNC1 | |||
| 55 | #elif HAVE_FUNCTION1 | |||
| 56 | #define __func__ __FUNCTION__ | |||
| 57 | #else | |||
| 58 | static char const __func__[] = "tport_type_tls"; | |||
| 59 | #endif | |||
| 60 | ||||
| 61 | #if HAVE_WIN32 | |||
| 62 | #include <io.h> | |||
| 63 | #define access(_filename, _mode) _access(_filename, _mode) | |||
| 64 | #define R_OK4 (04) | |||
| 65 | #endif | |||
| 66 | ||||
| 67 | /* ---------------------------------------------------------------------- */ | |||
| 68 | /* TLS */ | |||
| 69 | ||||
| 70 | #include "tport_tls.h" | |||
| 71 | ||||
| 72 | static int tport_tls_init_primary(tport_primary_t *, | |||
| 73 | tp_name_t tpn[1], | |||
| 74 | su_addrinfo_t *, tagi_t const *, | |||
| 75 | char const **return_culprit); | |||
| 76 | static int tport_tls_init_client(tport_primary_t *, | |||
| 77 | tp_name_t tpn[1], | |||
| 78 | su_addrinfo_t *, tagi_t const *, | |||
| 79 | char const **return_culprit); | |||
| 80 | static int tport_tls_init_master(tport_primary_t *pri, | |||
| 81 | tp_name_t tpn[1], | |||
| 82 | su_addrinfo_t *ai, | |||
| 83 | tagi_t const *tags, | |||
| 84 | char const **return_culprit); | |||
| 85 | static void tport_tls_deinit_primary(tport_primary_t *pri); | |||
| 86 | static int tport_tls_init_secondary(tport_t *self, int socket, int accepted, | |||
| 87 | char const **return_reason); | |||
| 88 | static void tport_tls_deinit_secondary(tport_t *self); | |||
| 89 | static void tport_tls_shutdown(tport_t *self, int how); | |||
| 90 | static int tport_tls_set_events(tport_t const *self); | |||
| 91 | static int tport_tls_events(tport_t *self, int events); | |||
| 92 | static int tport_tls_recv(tport_t *self); | |||
| 93 | static ssize_t tport_tls_send(tport_t const *self, msg_t *msg, | |||
| 94 | msg_iovec_t iov[], size_t iovused); | |||
| 95 | static int tport_tls_accept(tport_primary_t *pri, int events); | |||
| 96 | static tport_t *tport_tls_connect(tport_primary_t *pri, su_addrinfo_t *ai, | |||
| 97 | tp_name_t const *tpn); | |||
| 98 | ||||
| 99 | tport_vtable_t const tport_tls_vtable = | |||
| 100 | { | |||
| 101 | /* vtp_name */ "tls", | |||
| 102 | /* vtp_public */ tport_type_local, | |||
| 103 | /* vtp_pri_size */ sizeof (tport_tls_primary_t), | |||
| 104 | /* vtp_init_primary */ tport_tls_init_primary, | |||
| 105 | /* vtp_deinit_primary */ tport_tls_deinit_primary, | |||
| 106 | /* vtp_wakeup_pri */ tport_tls_accept, | |||
| 107 | /* vtp_connect */ tport_tls_connect, | |||
| 108 | /* vtp_secondary_size */ sizeof (tport_tls_t), | |||
| 109 | /* vtp_init_secondary */ tport_tls_init_secondary, | |||
| 110 | /* vtp_deinit_secondary */ tport_tls_deinit_secondary, | |||
| 111 | /* vtp_shutdown */ tport_tls_shutdown, | |||
| 112 | /* vtp_set_events */ tport_tls_set_events, | |||
| 113 | /* vtp_wakeup */ tport_tls_events, | |||
| 114 | /* vtp_recv */ tport_tls_recv, | |||
| 115 | /* vtp_send */ tport_tls_send, | |||
| 116 | /* vtp_deliver */ NULL((void*)0), | |||
| 117 | /* vtp_prepare */ NULL((void*)0), | |||
| 118 | /* vtp_keepalive */ NULL((void*)0), | |||
| 119 | /* vtp_stun_response */ NULL((void*)0), | |||
| 120 | /* vtp_next_secondary_timer*/ NULL((void*)0), | |||
| 121 | /* vtp_secondary_timer */ NULL((void*)0), | |||
| 122 | }; | |||
| 123 | ||||
| 124 | tport_vtable_t const tport_tls_client_vtable = | |||
| 125 | { | |||
| 126 | /* vtp_name */ "tls", | |||
| 127 | /* vtp_public */ tport_type_client, | |||
| 128 | /* vtp_pri_size */ sizeof (tport_tls_primary_t), | |||
| 129 | /* vtp_init_primary */ tport_tls_init_client, | |||
| 130 | /* vtp_deinit_primary */ tport_tls_deinit_primary, | |||
| 131 | /* vtp_wakeup_pri */ tport_tls_accept, | |||
| 132 | /* vtp_connect */ tport_tls_connect, | |||
| 133 | /* vtp_secondary_size */ sizeof (tport_tls_t), | |||
| 134 | /* vtp_init_secondary */ tport_tls_init_secondary, | |||
| 135 | /* vtp_deinit_secondary */ tport_tls_deinit_secondary, | |||
| 136 | /* vtp_shutdown */ tport_tls_shutdown, | |||
| 137 | /* vtp_set_events */ tport_tls_set_events, | |||
| 138 | /* vtp_wakeup */ tport_tls_events, | |||
| 139 | /* vtp_recv */ tport_tls_recv, | |||
| 140 | /* vtp_send */ tport_tls_send, | |||
| 141 | /* vtp_deliver */ NULL((void*)0), | |||
| 142 | /* vtp_prepare */ NULL((void*)0), | |||
| 143 | /* vtp_keepalive */ NULL((void*)0), | |||
| 144 | /* vtp_stun_response */ NULL((void*)0), | |||
| 145 | /* vtp_next_secondary_timer*/ NULL((void*)0), | |||
| 146 | /* vtp_secondary_timer */ NULL((void*)0), | |||
| 147 | }; | |||
| 148 | ||||
| 149 | static int tport_tls_init_primary(tport_primary_t *pri, | |||
| 150 | tp_name_t tpn[1], | |||
| 151 | su_addrinfo_t *ai, | |||
| 152 | tagi_t const *tags, | |||
| 153 | char const **return_culprit) | |||
| 154 | { | |||
| 155 | if (tport_tls_init_master(pri, tpn, ai, tags, return_culprit) < 0) | |||
| 156 | return -1; | |||
| 157 | ||||
| 158 | return tport_tcp_init_primary(pri, tpn, ai, tags, return_culprit); | |||
| 159 | } | |||
| 160 | ||||
| 161 | static int tport_tls_init_client(tport_primary_t *pri, | |||
| 162 | tp_name_t tpn[1], | |||
| 163 | su_addrinfo_t *ai, | |||
| 164 | tagi_t const *tags, | |||
| 165 | char const **return_culprit) | |||
| 166 | { | |||
| 167 | if (tport_tls_init_master(pri, tpn, ai, tags, return_culprit) < 0) | |||
| 168 | return -1; | |||
| 169 | ||||
| 170 | return tport_tcp_init_client(pri, tpn, ai, tags, return_culprit); | |||
| 171 | } | |||
| 172 | ||||
| 173 | static int tport_tls_init_master(tport_primary_t *pri, | |||
| 174 | tp_name_t tpn[1], | |||
| 175 | su_addrinfo_t *ai, | |||
| 176 | tagi_t const *tags, | |||
| 177 | char const **return_culprit) | |||
| 178 | { | |||
| 179 | tport_tls_primary_t *tlspri = (tport_tls_primary_t *)pri; | |||
| 180 | char *homedir; | |||
| 181 | char *tbf = NULL((void*)0); | |||
| 182 | char const *path = NULL((void*)0); | |||
| 183 | char const *tls_ciphers = NULL((void*)0); | |||
| 184 | unsigned tls_version = 1; | |||
| 185 | unsigned tls_timeout = 300; | |||
| 186 | unsigned tls_verify = 0; | |||
| 187 | char const *passphrase = NULL((void*)0); | |||
| 188 | unsigned tls_policy = TPTLS_VERIFY_NONE; | |||
| 189 | unsigned tls_depth = 0; | |||
| 190 | unsigned tls_date = 1; | |||
| 191 | su_strlst_t const *tls_subjects = NULL((void*)0); | |||
| 192 | su_home_t autohome[SU_HOME_AUTO_SIZE(1024)(((1024) + ((sizeof(su_home_t) + 7) & (size_t)~8) + ((3 * sizeof (void *) + 4 * sizeof(unsigned) + 7 * (sizeof (long) + sizeof(void *)) + 7) & (size_t)~8)) / sizeof(su_home_t))]; | |||
| 193 | tls_issues_t ti = {0}; | |||
| 194 | ||||
| 195 | su_home_auto(autohome, sizeof autohome); | |||
| 196 | ||||
| 197 | if (getenv("TPORT_SSL")) | |||
| 198 | tls_version = 0; | |||
| 199 | ||||
| 200 | tl_gets(tags, | |||
| 201 | TPTAG_CERTIFICATE_REF(path)tptag_certificate_ref, tag_str_vr(&(path)), | |||
| 202 | TPTAG_TLS_CIPHERS_REF(tls_ciphers)tptag_tls_ciphers_ref, tag_str_vr(&(tls_ciphers)), | |||
| 203 | TPTAG_TLS_VERSION_REF(tls_version)tptag_tls_version_ref, tag_uint_vr(&(tls_version)), | |||
| 204 | TPTAG_TLS_TIMEOUT_REF(tls_timeout)tptag_tls_timeout_ref, tag_uint_vr(&(tls_timeout)), | |||
| 205 | TPTAG_TLS_VERIFY_PEER_REF(tls_verify)tptag_tls_verify_peer_ref, tag_uint_vr(&(tls_verify)), | |||
| 206 | TPTAG_TLS_PASSPHRASE_REF(passphrase)tptag_tls_passphrase_ref, tag_str_vr(&(passphrase)), | |||
| 207 | TPTAG_TLS_VERIFY_POLICY_REF(tls_policy)tptag_tls_verify_policy_ref, tag_uint_vr(&(tls_policy)), | |||
| 208 | TPTAG_TLS_VERIFY_DEPTH_REF(tls_depth)tptag_tls_verify_depth_ref, tag_uint_vr(&(tls_depth)), | |||
| 209 | TPTAG_TLS_VERIFY_DATE_REF(tls_date)tptag_tls_verify_date_ref, tag_uint_vr(&(tls_date)), | |||
| 210 | TPTAG_TLS_VERIFY_SUBJECTS_REF(tls_subjects)tptag_tls_verify_subjects_ref, tag_cptr_vr(&(tls_subjects ), (tls_subjects)), | |||
| 211 | TAG_END()(tag_type_t)0, (tag_value_t)0); | |||
| 212 | ||||
| 213 | if (!path) { | |||
| 214 | homedir = getenv("HOME"); | |||
| 215 | if (!homedir) | |||
| 216 | homedir = ""; | |||
| 217 | path = tbf = su_sprintf(autohome, "%s/.sip/auth", homedir); | |||
| 218 | } | |||
| 219 | ||||
| 220 | if (path) { | |||
| 221 | ti.policy = tls_policy | (tls_verify ? TPTLS_VERIFY_ALL : 0); | |||
| 222 | ti.verify_depth = tls_depth; | |||
| 223 | ti.verify_date = tls_date; | |||
| 224 | ti.configured = path != tbf; | |||
| 225 | ti.randFile = su_sprintf(autohome, "%s/%s", path, "tls_seed.dat"); | |||
| 226 | ti.key = su_sprintf(autohome, "%s/%s", path, "agent.pem"); | |||
| 227 | if (access(ti.key, R_OK4) != 0) ti.key = NULL((void*)0); | |||
| 228 | if (!ti.key) ti.key = su_sprintf(autohome, "%s/%s", path, "tls.pem"); | |||
| 229 | ti.passphrase = su_strdup(autohome, passphrase); | |||
| 230 | ti.cert = ti.key; | |||
| 231 | ti.CAfile = su_sprintf(autohome, "%s/%s", path, "cafile.pem"); | |||
| 232 | if (access(ti.CAfile, R_OK4) != 0) ti.CAfile = NULL((void*)0); | |||
| 233 | if (!ti.CAfile) ti.CAfile = su_sprintf(autohome, "%s/%s", path, "tls.pem"); | |||
| 234 | if (tls_ciphers) ti.ciphers = su_strdup(autohome, tls_ciphers); | |||
| 235 | ti.version = tls_version; | |||
| 236 | ti.timeout = tls_timeout; | |||
| 237 | ti.CApath = su_strdup(autohome, path); | |||
| 238 | ||||
| 239 | SU_DEBUG_9(("%s(%p): tls key = %s\n", __func__, (void *)pri, ti.key))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 9 ? (_su_llog(tport_log, 9, "tport_type_tls.c" , (const char *)__func__, 239, "%s(%p): tls key = %s\n", __func__ , (void *)pri, ti.key)) : (void)0); | |||
| 240 | ||||
| 241 | if (ti.key && ti.CAfile && ti.randFile) { | |||
| 242 | if (access(ti.key, R_OK4) != 0) ti.key = NULL((void*)0); | |||
| 243 | if (access(ti.randFile, R_OK4) != 0) ti.randFile = NULL((void*)0); | |||
| 244 | if (access(ti.CAfile, R_OK4) != 0) ti.CAfile = NULL((void*)0); | |||
| 245 | tlspri->tlspri_master = tls_init_master(&ti); | |||
| 246 | } | |||
| 247 | } | |||
| 248 | ||||
| 249 | su_home_zap(autohome)su_home_unref((autohome)); | |||
| 250 | ||||
| 251 | if (!tlspri->tlspri_master) { | |||
| 252 | /* | |||
| 253 | if (!path || ti.configured) { | |||
| 254 | SU_DEBUG_1(("tls_init_master: %s\n", strerror(errno))); | |||
| 255 | } | |||
| 256 | else { | |||
| 257 | SU_DEBUG_5(("tls_init_master: %s\n", strerror(errno))); | |||
| 258 | } | |||
| 259 | */ | |||
| 260 | return *return_culprit = "tls_init_master", -1; | |||
| 261 | } else { | |||
| 262 | char buf[TPORT_HOSTPORTSIZE(55)]; | |||
| 263 | su_sockaddr_t *sa = ai ? (void *)(ai->ai_addr) : NULL((void*)0); | |||
| 264 | if (sa && tport_hostport(buf, sizeof(buf), sa, 2)) | |||
| 265 | SU_DEBUG_5(("%s(%p): tls context initialized for %s\n", \(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 5 ? (_su_llog(tport_log, 5, "tport_type_tls.c" , (const char *)__func__, 266, "%s(%p): tls context initialized for %s\n" , __func__, (void *)pri, buf)) : (void)0) | |||
| 266 | __func__, (void *)pri, buf))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 5 ? (_su_llog(tport_log, 5, "tport_type_tls.c" , (const char *)__func__, 266, "%s(%p): tls context initialized for %s\n" , __func__, (void *)pri, buf)) : (void)0); | |||
| 267 | } | |||
| 268 | ||||
| 269 | if (tls_subjects) | |||
| 270 | pri->pri_primary->tp_subjects = su_strlst_dup(pri->pri_homepri_primary->tp_home, tls_subjects); | |||
| 271 | pri->pri_has_tls = 1; | |||
| 272 | ||||
| 273 | return 0; | |||
| 274 | } | |||
| 275 | ||||
| 276 | static void tport_tls_deinit_primary(tport_primary_t *pri) | |||
| 277 | { | |||
| 278 | tport_tls_primary_t *tlspri = (tport_tls_primary_t *)pri; | |||
| 279 | tls_free(tlspri->tlspri_master), tlspri->tlspri_master = NULL((void*)0); | |||
| 280 | } | |||
| 281 | ||||
| 282 | static int tport_tls_init_secondary(tport_t *self, int socket, int accepted, | |||
| 283 | char const **return_reason) | |||
| 284 | { | |||
| 285 | tport_tls_primary_t *tlspri = (tport_tls_primary_t *)self->tp_pri; | |||
| 286 | tport_tls_t *tlstp = (tport_tls_t *)self; | |||
| 287 | ||||
| 288 | tls_t *master = tlspri->tlspri_master; | |||
| 289 | ||||
| 290 | if (tport_tcp_init_secondary(self, socket, accepted, return_reason) < 0) | |||
| 291 | return -1; | |||
| 292 | ||||
| 293 | tlstp->tlstp_context = tls_init_secondary(master, socket, accepted); | |||
| 294 | if (!tlstp->tlstp_context) | |||
| 295 | return *return_reason = "tls_init_slave", -1; | |||
| 296 | ||||
| 297 | return 0; | |||
| 298 | } | |||
| 299 | ||||
| 300 | static void tport_tls_deinit_secondary(tport_t *self) | |||
| 301 | { | |||
| 302 | tport_tls_t *tlstp = (tport_tls_t *)self; | |||
| 303 | ||||
| 304 | /* XXX - PPe: does the tls_shutdown zap everything but socket? */ | |||
| 305 | if (tlstp->tlstp_context != NULL((void*)0)) | |||
| 306 | tls_free(tlstp->tlstp_context); | |||
| 307 | tlstp->tlstp_context = NULL((void*)0); | |||
| 308 | ||||
| 309 | su_free(self->tp_home, tlstp->tlstp_buffer); | |||
| 310 | tlstp->tlstp_buffer = NULL((void*)0); | |||
| 311 | } | |||
| 312 | ||||
| 313 | static void tport_tls_shutdown(tport_t *self, int how) | |||
| 314 | { | |||
| 315 | tport_tls_t *tlstp = (tport_tls_t *)self; | |||
| 316 | ||||
| 317 | /* XXX - send alert */ | |||
| 318 | (void)tlstp; | |||
| 319 | ||||
| 320 | shutdown(self->tp_socket, how); | |||
| 321 | ||||
| 322 | if (how >= 2) | |||
| 323 | tport_tls_deinit_secondary(self); | |||
| 324 | } | |||
| 325 | ||||
| 326 | ||||
| 327 | static | |||
| 328 | int tport_tls_set_events(tport_t const *self) | |||
| 329 | { | |||
| 330 | tport_tls_t *tlstp = (tport_tls_t *)self; | |||
| 331 | int mask = tls_events(tlstp->tlstp_context, self->tp_events); | |||
| 332 | ||||
| 333 | SU_DEBUG_7(("%s(%p): logical events%s%s real%s%s\n",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 338, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_set_events", (void *)self, (self->tp_events & (0x001)) ? " IN" : "", (self->tp_events & (0x004)) ? " OUT" : "", (mask & (0x001)) ? " IN" : "", (mask & (0x004) ) ? " OUT" : "")) : (void)0) | |||
| 334 | "tport_tls_set_events", (void *)self,(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 338, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_set_events", (void *)self, (self->tp_events & (0x001)) ? " IN" : "", (self->tp_events & (0x004)) ? " OUT" : "", (mask & (0x001)) ? " IN" : "", (mask & (0x004) ) ? " OUT" : "")) : (void)0) | |||
| 335 | (self->tp_events & SU_WAIT_IN) ? " IN" : "",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 338, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_set_events", (void *)self, (self->tp_events & (0x001)) ? " IN" : "", (self->tp_events & (0x004)) ? " OUT" : "", (mask & (0x001)) ? " IN" : "", (mask & (0x004) ) ? " OUT" : "")) : (void)0) | |||
| 336 | (self->tp_events & SU_WAIT_OUT) ? " OUT" : "",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 338, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_set_events", (void *)self, (self->tp_events & (0x001)) ? " IN" : "", (self->tp_events & (0x004)) ? " OUT" : "", (mask & (0x001)) ? " IN" : "", (mask & (0x004) ) ? " OUT" : "")) : (void)0) | |||
| 337 | (mask & SU_WAIT_IN) ? " IN" : "",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 338, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_set_events", (void *)self, (self->tp_events & (0x001)) ? " IN" : "", (self->tp_events & (0x004)) ? " OUT" : "", (mask & (0x001)) ? " IN" : "", (mask & (0x004) ) ? " OUT" : "")) : (void)0) | |||
| 338 | (mask & SU_WAIT_OUT) ? " OUT" : ""))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 338, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_set_events", (void *)self, (self->tp_events & (0x001)) ? " IN" : "", (self->tp_events & (0x004)) ? " OUT" : "", (mask & (0x001)) ? " IN" : "", (mask & (0x004) ) ? " OUT" : "")) : (void)0); | |||
| 339 | ||||
| 340 | return | |||
| 341 | su_root_eventmask(self->tp_master->mr_root, | |||
| 342 | self->tp_index, | |||
| 343 | self->tp_socket, | |||
| 344 | mask); | |||
| 345 | } | |||
| 346 | ||||
| 347 | /** Handle poll events for tls */ | |||
| 348 | int tport_tls_events(tport_t *self, int events) | |||
| 349 | { | |||
| 350 | tport_tls_t *tlstp = (tport_tls_t *)self; | |||
| 351 | int old_mask = tls_events(tlstp->tlstp_context, self->tp_events), mask; | |||
| 352 | int ret, error = 0; | |||
| 353 | ||||
| 354 | if (events & SU_WAIT_ERR(0x008)) | |||
| 355 | error = tport_error_event(self); | |||
| 356 | ||||
| 357 | if ((self->tp_events & SU_WAIT_OUT(0x004)) && !self->tp_closed) { | |||
| 358 | ret = tls_want_write(tlstp->tlstp_context, events); | |||
| 359 | if (ret > 0) | |||
| 360 | tport_send_event(self); | |||
| 361 | else if (ret < 0) | |||
| 362 | tport_error_report(self, errno(*__errno_location ()), NULL((void*)0)); | |||
| 363 | } | |||
| 364 | ||||
| 365 | if ((self->tp_events & SU_WAIT_IN(0x001)) && !self->tp_closed) { | |||
| 366 | for (;;) { | |||
| 367 | ret = tls_want_read(tlstp->tlstp_context, events); | |||
| 368 | if (ret > 1) { | |||
| 369 | tport_recv_event(self); | |||
| 370 | if ((events & SU_WAIT_HUP(0x010)) && !self->tp_closed) | |||
| 371 | continue; | |||
| 372 | } | |||
| 373 | break; | |||
| 374 | } | |||
| 375 | ||||
| 376 | if (ret == 0) { /* End-of-stream */ | |||
| 377 | if (self->tp_msg) | |||
| 378 | tport_recv_event(self); | |||
| 379 | tport_shutdown0(self, 2); | |||
| 380 | } | |||
| 381 | ||||
| 382 | if (ret < 0) | |||
| 383 | tport_error_report(self, errno(*__errno_location ()), NULL((void*)0)); | |||
| 384 | } | |||
| 385 | ||||
| 386 | if ((events & SU_WAIT_HUP(0x010)) && !self->tp_closed) | |||
| 387 | tport_hup_event(self); | |||
| 388 | ||||
| 389 | if (error && !self->tp_closed) | |||
| 390 | tport_error_report(self, error, NULL((void*)0)); | |||
| 391 | ||||
| 392 | if (self->tp_closed) | |||
| 393 | return 0; | |||
| 394 | ||||
| 395 | events = self->tp_events; | |||
| 396 | mask = tls_events(tlstp->tlstp_context, events); | |||
| 397 | if ((old_mask ^ mask) == 0) | |||
| 398 | return 0; | |||
| 399 | ||||
| 400 | SU_DEBUG_7(("%s(%p): logical events%s%s real%s%s\n",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 405, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_events", (void *)self, (events & (0x001)) ? " IN" : "", (events & (0x004)) ? " OUT" : "", (mask & (0x001 )) ? " IN" : "", (mask & (0x004)) ? " OUT" : "")) : (void )0) | |||
| 401 | "tport_tls_events", (void *)self,(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 405, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_events", (void *)self, (events & (0x001)) ? " IN" : "", (events & (0x004)) ? " OUT" : "", (mask & (0x001 )) ? " IN" : "", (mask & (0x004)) ? " OUT" : "")) : (void )0) | |||
| 402 | (events & SU_WAIT_IN) ? " IN" : "",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 405, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_events", (void *)self, (events & (0x001)) ? " IN" : "", (events & (0x004)) ? " OUT" : "", (mask & (0x001 )) ? " IN" : "", (mask & (0x004)) ? " OUT" : "")) : (void )0) | |||
| 403 | (events & SU_WAIT_OUT) ? " OUT" : "",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 405, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_events", (void *)self, (events & (0x001)) ? " IN" : "", (events & (0x004)) ? " OUT" : "", (mask & (0x001 )) ? " IN" : "", (mask & (0x004)) ? " OUT" : "")) : (void )0) | |||
| 404 | (mask & SU_WAIT_IN) ? " IN" : "",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 405, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_events", (void *)self, (events & (0x001)) ? " IN" : "", (events & (0x004)) ? " OUT" : "", (mask & (0x001 )) ? " IN" : "", (mask & (0x004)) ? " OUT" : "")) : (void )0) | |||
| 405 | (mask & SU_WAIT_OUT) ? " OUT" : ""))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 405, "%s(%p): logical events%s%s real%s%s\n" , "tport_tls_events", (void *)self, (events & (0x001)) ? " IN" : "", (events & (0x004)) ? " OUT" : "", (mask & (0x001 )) ? " IN" : "", (mask & (0x004)) ? " OUT" : "")) : (void )0); | |||
| 406 | ||||
| 407 | su_root_eventmask(self->tp_master->mr_root, | |||
| 408 | self->tp_index, | |||
| 409 | self->tp_socket, | |||
| 410 | mask); | |||
| 411 | ||||
| 412 | return 0; | |||
| 413 | } | |||
| 414 | ||||
| 415 | /** Receive data from TLS. | |||
| 416 | * | |||
| 417 | * @retval -1 error | |||
| 418 | * @retval 0 end-of-stream | |||
| 419 | * @retval 1 normal receive | |||
| 420 | * @retval 2 incomplete recv, recv again | |||
| 421 | * | |||
| 422 | */ | |||
| 423 | static | |||
| 424 | int tport_tls_recv(tport_t *self) | |||
| 425 | { | |||
| 426 | tport_tls_t *tlstp = (tport_tls_t *)self; | |||
| 427 | msg_t *msg; | |||
| 428 | ssize_t n, N, veclen, i, m; | |||
| 429 | msg_iovec_t iovec[msg_n_fragments] = {{ 0 }}; | |||
| 430 | char *tls_buf; | |||
| 431 | ||||
| 432 | N = tls_read(tlstp->tlstp_context); | |||
| 433 | ||||
| 434 | SU_DEBUG_7(("%s(%p): tls_read() returned "MOD_ZD"\n", __func__, (void *)self, N))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 7 ? (_su_llog(tport_log, 7, "tport_type_tls.c" , (const char *)__func__, 434, "%s(%p): tls_read() returned " "%zd""\n", __func__, (void *)self, N)) : (void)0); | |||
| 435 | ||||
| 436 | if (N == 0) { | |||
| 437 | if (self->tp_msg) | |||
| 438 | msg_recv_commit(self->tp_msg, 0, 1); /* End-of-stream */ | |||
| 439 | return 0; | |||
| 440 | } | |||
| 441 | else if (N == -1) { | |||
| 442 | if (su_is_blocking(su_errno())((su_errno()) == 115 || (su_errno()) == 11 || (su_errno()) == 11 || (su_errno()) == 4)) { | |||
| 443 | tport_tls_set_events(self); | |||
| 444 | return 1; | |||
| 445 | } | |||
| 446 | return -1; | |||
| 447 | } | |||
| 448 | ||||
| 449 | veclen = tport_recv_iovec(self, &self->tp_msg, iovec, N, 0); | |||
| 450 | if (veclen < 0) | |||
| 451 | return -1; | |||
| 452 | ||||
| 453 | msg = self->tp_msg; | |||
| 454 | ||||
| 455 | tls_buf = tls_read_buffer(tlstp->tlstp_context, N); | |||
| 456 | ||||
| 457 | msg_set_address(msg, self->tp_addr, self->tp_addrlentp_addrinfo->ai_addrlen); | |||
| 458 | ||||
| 459 | for (i = 0, n = 0; i < veclen; i++) { | |||
| 460 | m = iovec[i].mv_lensiv_len; assert(N >= n + m)((void) sizeof ((N >= n + m) ? 1 : 0), __extension__ ({ if (N >= n + m) ; else __assert_fail ("N >= n + m", "tport_type_tls.c" , 460, __extension__ __PRETTY_FUNCTION__); })); | |||
| 461 | memcpy(iovec[i].mv_basesiv_base, tls_buf + n, m); | |||
| 462 | n += m; | |||
| 463 | } | |||
| 464 | ||||
| 465 | assert(N == n)((void) sizeof ((N == n) ? 1 : 0), __extension__ ({ if (N == n ) ; else __assert_fail ("N == n", "tport_type_tls.c", 465, __extension__ __PRETTY_FUNCTION__); })); | |||
| 466 | ||||
| 467 | /* Write the received data to the message dump file */ | |||
| 468 | if (self->tp_master->mr_dump_file) | |||
| 469 | tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from"); | |||
| 470 | ||||
| 471 | if (self->tp_master->mr_capt_sock) | |||
| 472 | tport_capt_msg(self, msg, n, iovec, veclen, "recv"); | |||
| 473 | ||||
| 474 | /* Mark buffer as used */ | |||
| 475 | msg_recv_commit(msg, N, 0); | |||
| 476 | ||||
| 477 | return tls_pending(tlstp->tlstp_context) ? 2 : 1; | |||
| 478 | } | |||
| 479 | ||||
| 480 | static | |||
| 481 | ssize_t tport_tls_send(tport_t const *self, | |||
| 482 | msg_t *msg, | |||
| 483 | msg_iovec_t iov[], | |||
| 484 | size_t iovlen) | |||
| 485 | { | |||
| 486 | tport_tls_t *tlstp = (tport_tls_t *)self; | |||
| 487 | enum { TLSBUFSIZE = 2048 }; | |||
| 488 | size_t i, j, n, m, size = 0; | |||
| 489 | ssize_t nerror; | |||
| 490 | int oldmask, mask; | |||
| 491 | ||||
| 492 | oldmask = tls_events(tlstp->tlstp_context, self->tp_events); | |||
| 493 | ||||
| 494 | #if 0 | |||
| 495 | if (!tlstp->tlstp_buffer) | |||
| 496 | tlstp->tlstp_buffer = su_alloc(self->tp_home, TLSBUFSIZE); | |||
| 497 | #endif | |||
| 498 | ||||
| 499 | for (i = 0; i < iovlen; i = j) { | |||
| 500 | #if 0 | |||
| 501 | nerror = tls_write(tlstp->tlstp_context, | |||
| 502 | iov[i].siv_base, | |||
| 503 | m = iov[i].siv_len); | |||
| 504 | j = i + 1; | |||
| 505 | #else | |||
| 506 | char *buf = tlstp->tlstp_buffer; | |||
| 507 | unsigned tlsbufsize = TLSBUFSIZE; | |||
| 508 | ||||
| 509 | if (i + 1 == iovlen) | |||
| 510 | buf = NULL((void*)0); /* Don't bother copying single chunk */ | |||
| 511 | ||||
| 512 | if (buf && | |||
| 513 | (char *)iov[i].siv_base - buf < TLSBUFSIZE && | |||
| 514 | (char *)iov[i].siv_base - buf >= 0) { | |||
| 515 | tlsbufsize = buf + TLSBUFSIZE - (char *)iov[i].siv_base; | |||
| 516 | assert(tlsbufsize <= TLSBUFSIZE)((void) sizeof ((tlsbufsize <= TLSBUFSIZE) ? 1 : 0), __extension__ ({ if (tlsbufsize <= TLSBUFSIZE) ; else __assert_fail ("tlsbufsize <= TLSBUFSIZE" , "tport_type_tls.c", 516, __extension__ __PRETTY_FUNCTION__) ; })); | |||
| 517 | } | |||
| 518 | ||||
| 519 | for (j = i, m = 0; buf && j < iovlen; j++) { | |||
| 520 | if (m + iov[j].siv_len > tlsbufsize) | |||
| 521 | break; | |||
| 522 | if (buf + m != iov[j].siv_base) | |||
| 523 | memcpy(buf + m, iov[j].siv_base, iov[j].siv_len); | |||
| 524 | m += iov[j].siv_len; iov[j].siv_len = 0; | |||
| 525 | } | |||
| 526 | ||||
| 527 | if (j == i) | |||
| 528 | buf = iov[i].siv_base, m = iov[i].siv_len, j++; | |||
| 529 | else | |||
| 530 | iov[j].siv_base = buf, iov[j].siv_len = m; | |||
| 531 | ||||
| 532 | nerror = tls_write(tlstp->tlstp_context, buf, m); | |||
| 533 | #endif | |||
| 534 | ||||
| 535 | SU_DEBUG_9(("tport_tls_writevec: vec %p %p %lu ("MOD_ZD")\n",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 9 ? (_su_llog(tport_log, 9, "tport_type_tls.c" , (const char *)__func__, 537, "tport_tls_writevec: vec %p %p %lu (" "%zd"")\n", (void *)tlstp->tlstp_context, (void *)iov[i].siv_base , (LU)iov[i].siv_len, nerror)) : (void)0) | |||
| 536 | (void *)tlstp->tlstp_context, (void *)iov[i].siv_base, (LU)iov[i].siv_len,(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 9 ? (_su_llog(tport_log, 9, "tport_type_tls.c" , (const char *)__func__, 537, "tport_tls_writevec: vec %p %p %lu (" "%zd"")\n", (void *)tlstp->tlstp_context, (void *)iov[i].siv_base , (LU)iov[i].siv_len, nerror)) : (void)0) | |||
| 537 | nerror))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 9 ? (_su_llog(tport_log, 9, "tport_type_tls.c" , (const char *)__func__, 537, "tport_tls_writevec: vec %p %p %lu (" "%zd"")\n", (void *)tlstp->tlstp_context, (void *)iov[i].siv_base , (LU)iov[i].siv_len, nerror)) : (void)0); | |||
| 538 | ||||
| 539 | if (nerror == -1) { | |||
| 540 | int err = su_errno(); | |||
| 541 | if (su_is_blocking(err)((err) == 115 || (err) == 11 || (err) == 11 || (err) == 4)) | |||
| 542 | break; | |||
| 543 | SU_DEBUG_3(("tls_write: %s\n", strerror(err)))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 543, "tls_write: %s\n", strerror(err ))) : (void)0); | |||
| 544 | return -1; | |||
| 545 | } | |||
| 546 | ||||
| 547 | n = (size_t)nerror; | |||
| 548 | size += n; | |||
| 549 | ||||
| 550 | /* Return if the write buffer is full for now */ | |||
| 551 | if (n != m) | |||
| 552 | break; | |||
| 553 | } | |||
| 554 | ||||
| 555 | mask = tls_events(tlstp->tlstp_context, self->tp_events); | |||
| 556 | ||||
| 557 | if (oldmask != mask) | |||
| 558 | tport_tls_set_events(self); | |||
| 559 | ||||
| 560 | return size; | |||
| 561 | } | |||
| 562 | ||||
| 563 | static | |||
| 564 | int tport_tls_accept(tport_primary_t *pri, int events) | |||
| 565 | { | |||
| 566 | tport_t *self; | |||
| 567 | su_addrinfo_t ai[1]; | |||
| 568 | su_sockaddr_t su[1]; | |||
| 569 | socklen_t sulen = sizeof su; | |||
| 570 | su_socket_t s = INVALID_SOCKET((su_socket_t)INVALID_SOCKET), l = pri->pri_primary->tp_socket; | |||
| 571 | char const *reason = "accept"; | |||
| 572 | ||||
| 573 | if (events & SU_WAIT_ERR(0x008)) | |||
| ||||
| 574 | tport_error_event(pri->pri_primary); | |||
| 575 | ||||
| 576 | if (!(events & SU_WAIT_ACCEPT(0x001))) | |||
| 577 | return 0; | |||
| 578 | ||||
| 579 | memcpy(ai, pri->pri_primary->tp_addrinfo, sizeof ai); | |||
| 580 | ai->ai_canonname = NULL((void*)0); | |||
| 581 | ||||
| 582 | s = accept(l, &su->su_sa, &sulen); | |||
| 583 | ||||
| 584 | if (s < 0) { | |||
| 585 | tport_error_report(pri->pri_primary, su_errno(), NULL((void*)0)); | |||
| 586 | return 0; | |||
| 587 | } | |||
| 588 | ||||
| 589 | ai->ai_addr = &su->su_sa, ai->ai_addrlen = sulen; | |||
| 590 | ||||
| 591 | /* Alloc a new transport object, then register socket events with it */ | |||
| 592 | if ((self = tport_alloc_secondary(pri, s, 1, &reason)) == NULL((void*)0)) { | |||
| 593 | SU_DEBUG_3(("%s(%p): incoming secondary on "TPN_FORMAT(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 595, "%s(%p): incoming secondary on " "%s/%s:%s%s%s%s%s" " failed. reason = %s\n", __func__, (void * )pri, (pri->pri_primary->tp_name)->tpn_proto, (pri-> pri_primary->tp_name)->tpn_host, (pri->pri_primary-> tp_name)->tpn_port, (pri->pri_primary->tp_name)-> tpn_comp ? ";comp=" : "", (pri->pri_primary->tp_name)-> tpn_comp ? (pri->pri_primary->tp_name)->tpn_comp : "" , (pri->pri_primary->tp_name)->tpn_ident ? "/" : "", (pri->pri_primary->tp_name)->tpn_ident ? (pri->pri_primary ->tp_name)->tpn_ident : "", reason)) : (void)0) | |||
| 594 | " failed. reason = %s\n", __func__, (void *)pri,(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 595, "%s(%p): incoming secondary on " "%s/%s:%s%s%s%s%s" " failed. reason = %s\n", __func__, (void * )pri, (pri->pri_primary->tp_name)->tpn_proto, (pri-> pri_primary->tp_name)->tpn_host, (pri->pri_primary-> tp_name)->tpn_port, (pri->pri_primary->tp_name)-> tpn_comp ? ";comp=" : "", (pri->pri_primary->tp_name)-> tpn_comp ? (pri->pri_primary->tp_name)->tpn_comp : "" , (pri->pri_primary->tp_name)->tpn_ident ? "/" : "", (pri->pri_primary->tp_name)->tpn_ident ? (pri->pri_primary ->tp_name)->tpn_ident : "", reason)) : (void)0) | |||
| 595 | TPN_ARGS(pri->pri_primary->tp_name), reason))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 595, "%s(%p): incoming secondary on " "%s/%s:%s%s%s%s%s" " failed. reason = %s\n", __func__, (void * )pri, (pri->pri_primary->tp_name)->tpn_proto, (pri-> pri_primary->tp_name)->tpn_host, (pri->pri_primary-> tp_name)->tpn_port, (pri->pri_primary->tp_name)-> tpn_comp ? ";comp=" : "", (pri->pri_primary->tp_name)-> tpn_comp ? (pri->pri_primary->tp_name)->tpn_comp : "" , (pri->pri_primary->tp_name)->tpn_ident ? "/" : "", (pri->pri_primary->tp_name)->tpn_ident ? (pri->pri_primary ->tp_name)->tpn_ident : "", reason)) : (void)0); | |||
| 596 | return 0; | |||
| 597 | } | |||
| 598 | else { | |||
| 599 | int events = SU_WAIT_IN(0x001)|SU_WAIT_ERR(0x008)|SU_WAIT_HUP(0x010); | |||
| 600 | ||||
| 601 | SU_CANONIZE_SOCKADDR(su)((su)->su_sa.sa_family == 10 ? su_canonize_sockaddr(su) : ( void)0); | |||
| ||||
| 602 | ||||
| 603 | if (/* Name this transport */ | |||
| 604 | tport_setname(self, pri->pri_protonamepri_primary->tp_name->tpn_proto, ai, NULL((void*)0)) != -1 | |||
| 605 | /* Register this secondary */ | |||
| 606 | && | |||
| 607 | tport_register_secondary(self, tls_connect, events) != -1) { | |||
| 608 | ||||
| 609 | self->tp_conn_orient = 1; | |||
| 610 | self->tp_is_connected = 0; | |||
| 611 | ||||
| 612 | SU_DEBUG_5(("%s(%p): new connection from " TPN_FORMAT "\n",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 5 ? (_su_llog(tport_log, 5, "tport_type_tls.c" , (const char *)__func__, 613, "%s(%p): new connection from " "%s/%s:%s%s%s%s%s" "\n", __func__, (void *)self, (self->tp_name )->tpn_proto, (self->tp_name)->tpn_host, (self->tp_name )->tpn_port, (self->tp_name)->tpn_comp ? ";comp=" : "" , (self->tp_name)->tpn_comp ? (self->tp_name)->tpn_comp : "", (self->tp_name)->tpn_ident ? "/" : "", (self-> tp_name)->tpn_ident ? (self->tp_name)->tpn_ident : "" )) : (void)0) | |||
| 613 | __func__, (void *)self, TPN_ARGS(self->tp_name)))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 5 ? (_su_llog(tport_log, 5, "tport_type_tls.c" , (const char *)__func__, 613, "%s(%p): new connection from " "%s/%s:%s%s%s%s%s" "\n", __func__, (void *)self, (self->tp_name )->tpn_proto, (self->tp_name)->tpn_host, (self->tp_name )->tpn_port, (self->tp_name)->tpn_comp ? ";comp=" : "" , (self->tp_name)->tpn_comp ? (self->tp_name)->tpn_comp : "", (self->tp_name)->tpn_ident ? "/" : "", (self-> tp_name)->tpn_ident ? (self->tp_name)->tpn_ident : "" )) : (void)0); | |||
| 614 | ||||
| 615 | /* Return succesfully */ | |||
| 616 | return 0; | |||
| 617 | } | |||
| 618 | ||||
| 619 | /* Failure: shutdown socket, */ | |||
| 620 | tport_close(self); | |||
| 621 | tport_zap_secondary(self); | |||
| 622 | self = NULL((void*)0); | |||
| 623 | } | |||
| 624 | ||||
| 625 | return 0; | |||
| 626 | } | |||
| 627 | ||||
| 628 | static | |||
| 629 | tport_t *tport_tls_connect(tport_primary_t *pri, | |||
| 630 | su_addrinfo_t *ai, | |||
| 631 | tp_name_t const *tpn) | |||
| 632 | { | |||
| 633 | tport_t *self = NULL((void*)0); | |||
| 634 | ||||
| 635 | su_socket_t s, server_socket; | |||
| 636 | int events = SU_WAIT_CONNECT(0x004) | SU_WAIT_ERR(0x008); | |||
| 637 | ||||
| 638 | int err; | |||
| 639 | unsigned errlevel = 3; | |||
| 640 | char buf[TPORT_HOSTPORTSIZE(55)]; | |||
| 641 | char const *what; | |||
| 642 | ||||
| 643 | what = "su_socket"; | |||
| 644 | s = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | |||
| 645 | if (s == INVALID_SOCKET((su_socket_t)INVALID_SOCKET)) | |||
| 646 | goto sys_error; | |||
| 647 | ||||
| 648 | what = "tport_alloc_secondary"; | |||
| 649 | if ((self = tport_alloc_secondary(pri, s, 0, &what)) == NULL((void*)0)) | |||
| 650 | goto sys_error; | |||
| 651 | ||||
| 652 | self->tp_conn_orient = 1; | |||
| 653 | ||||
| 654 | if ((server_socket = pri->pri_primary->tp_socket) != INVALID_SOCKET((su_socket_t)INVALID_SOCKET)) { | |||
| 655 | su_sockaddr_t susa; | |||
| 656 | socklen_t susalen = sizeof(susa); | |||
| 657 | ||||
| 658 | if (getsockname(server_socket, &susa.su_sa, &susalen) < 0) { | |||
| 659 | SU_DEBUG_3(("%s(%p): getsockname(): %s\n",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 660, "%s(%p): getsockname(): %s\n", __func__, (void *)self, su_strerror(su_errno()))) : (void)0) | |||
| 660 | __func__, (void *)self, su_strerror(su_errno())))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 660, "%s(%p): getsockname(): %s\n", __func__, (void *)self, su_strerror(su_errno()))) : (void)0); | |||
| 661 | } else { | |||
| 662 | susa.su_portsu_sin.sin_port = 0; | |||
| 663 | if (bind(s, &susa.su_sa, susalen) < 0) { | |||
| 664 | SU_DEBUG_3(("%s(%p): bind(local-ip): %s\n",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 665, "%s(%p): bind(local-ip): %s\n" , __func__, (void *)self, su_strerror(su_errno()))) : (void)0 ) | |||
| 665 | __func__, (void *)self, su_strerror(su_errno())))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 3 ? (_su_llog(tport_log, 3, "tport_type_tls.c" , (const char *)__func__, 665, "%s(%p): bind(local-ip): %s\n" , __func__, (void *)self, su_strerror(su_errno()))) : (void)0 ); | |||
| 666 | } | |||
| 667 | } | |||
| 668 | } | |||
| 669 | ||||
| 670 | what = "connect"; | |||
| 671 | if (connect(s, ai->ai_addr, (socklen_t)(ai->ai_addrlen)) == SOCKET_ERRORSOCKET_ERROR) { | |||
| 672 | err = su_errno(); | |||
| 673 | if (!su_is_blocking(err)((err) == 115 || (err) == 11 || (err) == 11 || (err) == 4)) | |||
| 674 | goto sys_error; | |||
| 675 | } | |||
| 676 | ||||
| 677 | what = "tport_setname"; | |||
| 678 | if (tport_setname(self, tpn->tpn_proto, ai, tpn->tpn_canon) == -1) | |||
| 679 | goto sys_error; | |||
| 680 | ||||
| 681 | what = "tport_register_secondary"; | |||
| 682 | if (tport_register_secondary(self, tls_connect, events) == -1) | |||
| 683 | goto sys_error; | |||
| 684 | ||||
| 685 | SU_DEBUG_5(("%s(%p): connecting to " TPN_FORMAT "\n",(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 5 ? (_su_llog(tport_log, 5, "tport_type_tls.c" , (const char *)__func__, 686, "%s(%p): connecting to " "%s/%s:%s%s%s%s%s" "\n", __func__, (void *)self, (self->tp_name)->tpn_proto , (self->tp_name)->tpn_host, (self->tp_name)->tpn_port , (self->tp_name)->tpn_comp ? ";comp=" : "", (self-> tp_name)->tpn_comp ? (self->tp_name)->tpn_comp : "", (self->tp_name)->tpn_ident ? "/" : "", (self->tp_name )->tpn_ident ? (self->tp_name)->tpn_ident : "")) : ( void)0) | |||
| 686 | __func__, (void *)self, TPN_ARGS(self->tp_name)))(((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log-> log_init > 1) ? tport_log->log_level : su_log_default-> log_level)) >= 5 ? (_su_llog(tport_log, 5, "tport_type_tls.c" , (const char *)__func__, 686, "%s(%p): connecting to " "%s/%s:%s%s%s%s%s" "\n", __func__, (void *)self, (self->tp_name)->tpn_proto , (self->tp_name)->tpn_host, (self->tp_name)->tpn_port , (self->tp_name)->tpn_comp ? ";comp=" : "", (self-> tp_name)->tpn_comp ? (self->tp_name)->tpn_comp : "", (self->tp_name)->tpn_ident ? "/" : "", (self->tp_name )->tpn_ident ? (self->tp_name)->tpn_ident : "")) : ( void)0); | |||
| 687 | ||||
| 688 | tport_set_secondary_timer(self); | |||
| 689 | ||||
| 690 | return self; | |||
| 691 | ||||
| 692 | sys_error: | |||
| 693 | err = errno(*__errno_location ()); | |||
| 694 | if (SU_LOG_LEVEL((tport_log != ((void*)0) && tport_log->log_init) == 0 ? 9 : ((tport_log != ((void*)0) && tport_log->log_init > 1) ? tport_log->log_level : su_log_default->log_level )) >= errlevel) | |||
| 695 | su_llog(tport_log, errlevel, "%s(%p): %s (pf=%d %s/%s): %s\n",_su_llog(tport_log, errlevel, "tport_type_tls.c", (const char *)__func__, 698, "%s(%p): %s (pf=%d %s/%s): %s\n", __func__, (void *)pri, what, ai->ai_family, tpn->tpn_proto, tport_hostport (buf, sizeof(buf), (void *)ai->ai_addr, 2), su_strerror(err )) | |||
| 696 | __func__, (void *)pri, what, ai->ai_family, tpn->tpn_proto,_su_llog(tport_log, errlevel, "tport_type_tls.c", (const char *)__func__, 698, "%s(%p): %s (pf=%d %s/%s): %s\n", __func__, (void *)pri, what, ai->ai_family, tpn->tpn_proto, tport_hostport (buf, sizeof(buf), (void *)ai->ai_addr, 2), su_strerror(err )) | |||
| 697 | tport_hostport(buf, sizeof(buf), (void *)ai->ai_addr, 2),_su_llog(tport_log, errlevel, "tport_type_tls.c", (const char *)__func__, 698, "%s(%p): %s (pf=%d %s/%s): %s\n", __func__, (void *)pri, what, ai->ai_family, tpn->tpn_proto, tport_hostport (buf, sizeof(buf), (void *)ai->ai_addr, 2), su_strerror(err )) | |||
| 698 | su_strerror(err))_su_llog(tport_log, errlevel, "tport_type_tls.c", (const char *)__func__, 698, "%s(%p): %s (pf=%d %s/%s): %s\n", __func__, (void *)pri, what, ai->ai_family, tpn->tpn_proto, tport_hostport (buf, sizeof(buf), (void *)ai->ai_addr, 2), su_strerror(err )); | |||
| 699 | tport_zap_secondary(self); | |||
| 700 | su_seterrno(err); | |||
| 701 | return NULL((void*)0); | |||
| 702 | } |