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