2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
15 #ifndef OPENSSL_NO_SOCK
17 typedef struct bio_connect_st
{
24 BIO_ADDRINFO
*addr_first
;
25 const BIO_ADDRINFO
*addr_iter
;
27 * int socket; this will be kept in bio->num so that it is compatible
28 * with the bss_sock bio
31 * called when the connection is initially made callback(BIO,state,ret);
32 * The callback should return 'ret'. state is for compatibility with the
35 BIO_info_cb
*info_callback
;
38 static int conn_write(BIO
*h
, const char *buf
, int num
);
39 static int conn_read(BIO
*h
, char *buf
, int size
);
40 static int conn_puts(BIO
*h
, const char *str
);
41 static long conn_ctrl(BIO
*h
, int cmd
, long arg1
, void *arg2
);
42 static int conn_new(BIO
*h
);
43 static int conn_free(BIO
*data
);
44 static long conn_callback_ctrl(BIO
*h
, int cmd
, BIO_info_cb
*);
46 static int conn_state(BIO
*b
, BIO_CONNECT
*c
);
47 static void conn_close_socket(BIO
*data
);
48 BIO_CONNECT
*BIO_CONNECT_new(void);
49 void BIO_CONNECT_free(BIO_CONNECT
*a
);
51 #define BIO_CONN_S_BEFORE 1
52 #define BIO_CONN_S_GET_ADDR 2
53 #define BIO_CONN_S_CREATE_SOCKET 3
54 #define BIO_CONN_S_CONNECT 4
55 #define BIO_CONN_S_OK 5
56 #define BIO_CONN_S_BLOCKED_CONNECT 6
58 static const BIO_METHOD methods_connectp
= {
61 /* TODO: Convert to new style write function */
64 /* TODO: Convert to new style read function */
68 NULL
, /* conn_gets, */
75 static int conn_state(BIO
*b
, BIO_CONNECT
*c
)
78 BIO_info_cb
*cb
= NULL
;
80 if (c
->info_callback
!= NULL
)
81 cb
= c
->info_callback
;
85 case BIO_CONN_S_BEFORE
:
86 if (c
->param_hostname
== NULL
&& c
->param_service
== NULL
) {
87 BIOerr(BIO_F_CONN_STATE
, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED
);
89 "hostname=", c
->param_hostname
,
90 " service=", c
->param_service
);
93 c
->state
= BIO_CONN_S_GET_ADDR
;
96 case BIO_CONN_S_GET_ADDR
:
98 int family
= AF_UNSPEC
;
99 switch (c
->connect_family
) {
100 case BIO_FAMILY_IPV6
:
101 if (1) { /* This is a trick we use to avoid bit rot.
102 * at least the "else" part will always be
109 BIOerr(BIO_F_CONN_STATE
, BIO_R_UNAVAILABLE_IP_FAMILY
);
113 case BIO_FAMILY_IPV4
:
116 case BIO_FAMILY_IPANY
:
120 BIOerr(BIO_F_CONN_STATE
, BIO_R_UNSUPPORTED_IP_FAMILY
);
123 if (BIO_lookup(c
->param_hostname
, c
->param_service
,
125 family
, SOCK_STREAM
, &c
->addr_first
) == 0)
128 if (c
->addr_first
== NULL
) {
129 BIOerr(BIO_F_CONN_STATE
, BIO_R_LOOKUP_RETURNED_NOTHING
);
132 c
->addr_iter
= c
->addr_first
;
133 c
->state
= BIO_CONN_S_CREATE_SOCKET
;
136 case BIO_CONN_S_CREATE_SOCKET
:
137 ret
= BIO_socket(BIO_ADDRINFO_family(c
->addr_iter
),
138 BIO_ADDRINFO_socktype(c
->addr_iter
),
139 BIO_ADDRINFO_protocol(c
->addr_iter
), 0);
140 if (ret
== (int)INVALID_SOCKET
) {
141 ERR_raise_data(ERR_LIB_SYS
, get_last_socket_error(),
142 "calling socket(%s, %s)",
143 c
->param_hostname
, c
->param_service
);
144 BIOerr(BIO_F_CONN_STATE
, BIO_R_UNABLE_TO_CREATE_SOCKET
);
148 c
->state
= BIO_CONN_S_CONNECT
;
151 case BIO_CONN_S_CONNECT
:
152 BIO_clear_retry_flags(b
);
153 ret
= BIO_connect(b
->num
, BIO_ADDRINFO_address(c
->addr_iter
),
154 BIO_SOCK_KEEPALIVE
| c
->connect_mode
);
157 if (BIO_sock_should_retry(ret
)) {
158 BIO_set_retry_special(b
);
159 c
->state
= BIO_CONN_S_BLOCKED_CONNECT
;
160 b
->retry_reason
= BIO_RR_CONNECT
;
162 } else if ((c
->addr_iter
= BIO_ADDRINFO_next(c
->addr_iter
))
165 * if there are more addresses to try, do that first
167 BIO_closesocket(b
->num
);
168 c
->state
= BIO_CONN_S_CREATE_SOCKET
;
172 ERR_raise_data(ERR_LIB_SYS
, get_last_socket_error(),
173 "calling connect(%s, %s)",
174 c
->param_hostname
, c
->param_service
);
175 BIOerr(BIO_F_CONN_STATE
, BIO_R_CONNECT_ERROR
);
179 c
->state
= BIO_CONN_S_OK
;
183 case BIO_CONN_S_BLOCKED_CONNECT
:
184 i
= BIO_sock_error(b
->num
);
186 BIO_clear_retry_flags(b
);
187 ERR_raise_data(ERR_LIB_SYS
, i
,
188 "calling connect(%s, %s)",
189 c
->param_hostname
, c
->param_service
);
190 BIOerr(BIO_F_CONN_STATE
, BIO_R_NBIO_CONNECT_ERROR
);
194 c
->state
= BIO_CONN_S_OK
;
206 if ((ret
= cb((BIO
*)b
, c
->state
, ret
)) == 0)
211 /* Loop does not exit */
214 ret
= cb((BIO
*)b
, c
->state
, ret
);
219 BIO_CONNECT
*BIO_CONNECT_new(void)
223 if ((ret
= OPENSSL_zalloc(sizeof(*ret
))) == NULL
) {
224 BIOerr(BIO_F_BIO_CONNECT_NEW
, ERR_R_MALLOC_FAILURE
);
227 ret
->state
= BIO_CONN_S_BEFORE
;
228 ret
->connect_family
= BIO_FAMILY_IPANY
;
232 void BIO_CONNECT_free(BIO_CONNECT
*a
)
236 OPENSSL_free(a
->param_hostname
);
237 OPENSSL_free(a
->param_service
);
238 BIO_ADDRINFO_free(a
->addr_first
);
242 const BIO_METHOD
*BIO_s_connect(void)
244 return &methods_connectp
;
247 static int conn_new(BIO
*bi
)
250 bi
->num
= (int)INVALID_SOCKET
;
252 if ((bi
->ptr
= (char *)BIO_CONNECT_new()) == NULL
)
258 static void conn_close_socket(BIO
*bio
)
262 c
= (BIO_CONNECT
*)bio
->ptr
;
263 if (bio
->num
!= (int)INVALID_SOCKET
) {
264 /* Only do a shutdown if things were established */
265 if (c
->state
== BIO_CONN_S_OK
)
266 shutdown(bio
->num
, 2);
267 BIO_closesocket(bio
->num
);
268 bio
->num
= (int)INVALID_SOCKET
;
272 static int conn_free(BIO
*a
)
278 data
= (BIO_CONNECT
*)a
->ptr
;
281 conn_close_socket(a
);
282 BIO_CONNECT_free(data
);
290 static int conn_read(BIO
*b
, char *out
, int outl
)
295 data
= (BIO_CONNECT
*)b
->ptr
;
296 if (data
->state
!= BIO_CONN_S_OK
) {
297 ret
= conn_state(b
, data
);
303 clear_socket_error();
304 ret
= readsocket(b
->num
, out
, outl
);
305 BIO_clear_retry_flags(b
);
307 if (BIO_sock_should_retry(ret
))
308 BIO_set_retry_read(b
);
314 static int conn_write(BIO
*b
, const char *in
, int inl
)
319 data
= (BIO_CONNECT
*)b
->ptr
;
320 if (data
->state
!= BIO_CONN_S_OK
) {
321 ret
= conn_state(b
, data
);
326 clear_socket_error();
327 ret
= writesocket(b
->num
, in
, inl
);
328 BIO_clear_retry_flags(b
);
330 if (BIO_sock_should_retry(ret
))
331 BIO_set_retry_write(b
);
336 static long conn_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
340 const char **pptr
= NULL
;
344 data
= (BIO_CONNECT
*)b
->ptr
;
349 data
->state
= BIO_CONN_S_BEFORE
;
350 conn_close_socket(b
);
351 BIO_ADDRINFO_free(data
->addr_first
);
352 data
->addr_first
= NULL
;
355 case BIO_C_DO_STATE_MACHINE
:
356 /* use this one to start the connection */
357 if (data
->state
!= BIO_CONN_S_OK
)
358 ret
= (long)conn_state(b
, data
);
362 case BIO_C_GET_CONNECT
:
364 pptr
= (const char **)ptr
;
366 *pptr
= data
->param_hostname
;
367 } else if (num
== 1) {
368 *pptr
= data
->param_service
;
369 } else if (num
== 2) {
370 *pptr
= (const char *)BIO_ADDRINFO_address(data
->addr_iter
);
371 } else if (num
== 3) {
372 switch (BIO_ADDRINFO_family(data
->addr_iter
)) {
375 ret
= BIO_FAMILY_IPV6
;
379 ret
= BIO_FAMILY_IPV4
;
382 ret
= data
->connect_family
;
395 case BIO_C_SET_CONNECT
:
399 char *hold_service
= data
->param_service
;
400 /* We affect the hostname regardless. However, the input
401 * string might contain a host:service spec, so we must
402 * parse it, which might or might not affect the service
404 OPENSSL_free(data
->param_hostname
);
405 data
->param_hostname
= NULL
;
406 ret
= BIO_parse_hostserv(ptr
,
407 &data
->param_hostname
,
408 &data
->param_service
,
409 BIO_PARSE_PRIO_HOST
);
410 if (hold_service
!= data
->param_service
)
411 OPENSSL_free(hold_service
);
412 } else if (num
== 1) {
413 OPENSSL_free(data
->param_service
);
414 data
->param_service
= BUF_strdup(ptr
);
415 } else if (num
== 2) {
416 const BIO_ADDR
*addr
= (const BIO_ADDR
*)ptr
;
418 data
->param_hostname
= BIO_ADDR_hostname_string(addr
, 1);
419 data
->param_service
= BIO_ADDR_service_string(addr
, 1);
420 BIO_ADDRINFO_free(data
->addr_first
);
421 data
->addr_first
= NULL
;
422 data
->addr_iter
= NULL
;
424 } else if (num
== 3) {
425 data
->connect_family
= *(int *)ptr
;
433 data
->connect_mode
|= BIO_SOCK_NONBLOCK
;
435 data
->connect_mode
&= ~BIO_SOCK_NONBLOCK
;
437 case BIO_C_SET_CONNECT_MODE
:
438 data
->connect_mode
= (int)num
;
449 case BIO_CTRL_GET_CLOSE
:
452 case BIO_CTRL_SET_CLOSE
:
453 b
->shutdown
= (int)num
;
455 case BIO_CTRL_PENDING
:
456 case BIO_CTRL_WPENDING
:
464 if (data
->param_hostname
)
465 BIO_set_conn_hostname(dbio
, data
->param_hostname
);
466 if (data
->param_service
)
467 BIO_set_conn_port(dbio
, data
->param_service
);
468 BIO_set_conn_ip_family(dbio
, data
->connect_family
);
469 BIO_set_conn_mode(dbio
, data
->connect_mode
);
471 * FIXME: the cast of the function seems unlikely to be a good
474 (void)BIO_set_info_callback(dbio
, data
->info_callback
);
477 case BIO_CTRL_SET_CALLBACK
:
478 ret
= 0; /* use callback ctrl */
480 case BIO_CTRL_GET_CALLBACK
:
484 fptr
= (BIO_info_cb
**)ptr
;
485 *fptr
= data
->info_callback
;
495 static long conn_callback_ctrl(BIO
*b
, int cmd
, BIO_info_cb
*fp
)
500 data
= (BIO_CONNECT
*)b
->ptr
;
503 case BIO_CTRL_SET_CALLBACK
:
505 data
->info_callback
= fp
;
515 static int conn_puts(BIO
*bp
, const char *str
)
520 ret
= conn_write(bp
, str
, n
);
524 BIO
*BIO_new_connect(const char *str
)
528 ret
= BIO_new(BIO_s_connect());
531 if (BIO_set_conn_hostname(ret
, str
))