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 | } |