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 SYSerr("socket", get_last_socket_error());
142 ERR_add_error_data(4,
143 "hostname=", c
->param_hostname
,
144 " service=", c
->param_service
);
145 BIOerr(BIO_F_CONN_STATE
, BIO_R_UNABLE_TO_CREATE_SOCKET
);
149 c
->state
= BIO_CONN_S_CONNECT
;
152 case BIO_CONN_S_CONNECT
:
153 BIO_clear_retry_flags(b
);
154 ret
= BIO_connect(b
->num
, BIO_ADDRINFO_address(c
->addr_iter
),
155 BIO_SOCK_KEEPALIVE
| c
->connect_mode
);
158 if (BIO_sock_should_retry(ret
)) {
159 BIO_set_retry_special(b
);
160 c
->state
= BIO_CONN_S_BLOCKED_CONNECT
;
161 b
->retry_reason
= BIO_RR_CONNECT
;
163 } else if ((c
->addr_iter
= BIO_ADDRINFO_next(c
->addr_iter
))
166 * if there are more addresses to try, do that first
168 BIO_closesocket(b
->num
);
169 c
->state
= BIO_CONN_S_CREATE_SOCKET
;
173 SYSerr("connect", get_last_socket_error());
174 ERR_add_error_data(4,
175 "hostname=", c
->param_hostname
,
176 " service=", c
->param_service
);
177 BIOerr(BIO_F_CONN_STATE
, BIO_R_CONNECT_ERROR
);
181 c
->state
= BIO_CONN_S_OK
;
185 case BIO_CONN_S_BLOCKED_CONNECT
:
186 i
= BIO_sock_error(b
->num
);
188 BIO_clear_retry_flags(b
);
189 SYSerr("connect", i
);
190 ERR_add_error_data(4,
191 "hostname=", c
->param_hostname
,
192 " service=", c
->param_service
);
193 BIOerr(BIO_F_CONN_STATE
, BIO_R_NBIO_CONNECT_ERROR
);
197 c
->state
= BIO_CONN_S_OK
;
209 if ((ret
= cb((BIO
*)b
, c
->state
, ret
)) == 0)
214 /* Loop does not exit */
217 ret
= cb((BIO
*)b
, c
->state
, ret
);
222 BIO_CONNECT
*BIO_CONNECT_new(void)
226 if ((ret
= OPENSSL_zalloc(sizeof(*ret
))) == NULL
) {
227 BIOerr(BIO_F_BIO_CONNECT_NEW
, ERR_R_MALLOC_FAILURE
);
230 ret
->state
= BIO_CONN_S_BEFORE
;
231 ret
->connect_family
= BIO_FAMILY_IPANY
;
235 void BIO_CONNECT_free(BIO_CONNECT
*a
)
239 OPENSSL_free(a
->param_hostname
);
240 OPENSSL_free(a
->param_service
);
241 BIO_ADDRINFO_free(a
->addr_first
);
245 const BIO_METHOD
*BIO_s_connect(void)
247 return &methods_connectp
;
250 static int conn_new(BIO
*bi
)
253 bi
->num
= (int)INVALID_SOCKET
;
255 if ((bi
->ptr
= (char *)BIO_CONNECT_new()) == NULL
)
261 static void conn_close_socket(BIO
*bio
)
265 c
= (BIO_CONNECT
*)bio
->ptr
;
266 if (bio
->num
!= (int)INVALID_SOCKET
) {
267 /* Only do a shutdown if things were established */
268 if (c
->state
== BIO_CONN_S_OK
)
269 shutdown(bio
->num
, 2);
270 BIO_closesocket(bio
->num
);
271 bio
->num
= (int)INVALID_SOCKET
;
275 static int conn_free(BIO
*a
)
281 data
= (BIO_CONNECT
*)a
->ptr
;
284 conn_close_socket(a
);
285 BIO_CONNECT_free(data
);
293 static int conn_read(BIO
*b
, char *out
, int outl
)
298 data
= (BIO_CONNECT
*)b
->ptr
;
299 if (data
->state
!= BIO_CONN_S_OK
) {
300 ret
= conn_state(b
, data
);
306 clear_socket_error();
307 ret
= readsocket(b
->num
, out
, outl
);
308 BIO_clear_retry_flags(b
);
310 if (BIO_sock_should_retry(ret
))
311 BIO_set_retry_read(b
);
317 static int conn_write(BIO
*b
, const char *in
, int inl
)
322 data
= (BIO_CONNECT
*)b
->ptr
;
323 if (data
->state
!= BIO_CONN_S_OK
) {
324 ret
= conn_state(b
, data
);
329 clear_socket_error();
330 ret
= writesocket(b
->num
, in
, inl
);
331 BIO_clear_retry_flags(b
);
333 if (BIO_sock_should_retry(ret
))
334 BIO_set_retry_write(b
);
339 static long conn_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
343 const char **pptr
= NULL
;
347 data
= (BIO_CONNECT
*)b
->ptr
;
352 data
->state
= BIO_CONN_S_BEFORE
;
353 conn_close_socket(b
);
354 BIO_ADDRINFO_free(data
->addr_first
);
355 data
->addr_first
= NULL
;
358 case BIO_C_DO_STATE_MACHINE
:
359 /* use this one to start the connection */
360 if (data
->state
!= BIO_CONN_S_OK
)
361 ret
= (long)conn_state(b
, data
);
365 case BIO_C_GET_CONNECT
:
367 pptr
= (const char **)ptr
;
369 *pptr
= data
->param_hostname
;
370 } else if (num
== 1) {
371 *pptr
= data
->param_service
;
372 } else if (num
== 2) {
373 *pptr
= (const char *)BIO_ADDRINFO_address(data
->addr_iter
);
374 } else if (num
== 3) {
375 switch (BIO_ADDRINFO_family(data
->addr_iter
)) {
378 ret
= BIO_FAMILY_IPV6
;
382 ret
= BIO_FAMILY_IPV4
;
385 ret
= data
->connect_family
;
398 case BIO_C_SET_CONNECT
:
402 char *hold_service
= data
->param_service
;
403 /* We affect the hostname regardless. However, the input
404 * string might contain a host:service spec, so we must
405 * parse it, which might or might not affect the service
407 OPENSSL_free(data
->param_hostname
);
408 data
->param_hostname
= NULL
;
409 ret
= BIO_parse_hostserv(ptr
,
410 &data
->param_hostname
,
411 &data
->param_service
,
412 BIO_PARSE_PRIO_HOST
);
413 if (hold_service
!= data
->param_service
)
414 OPENSSL_free(hold_service
);
415 } else if (num
== 1) {
416 OPENSSL_free(data
->param_service
);
417 data
->param_service
= BUF_strdup(ptr
);
418 } else if (num
== 2) {
419 const BIO_ADDR
*addr
= (const BIO_ADDR
*)ptr
;
421 data
->param_hostname
= BIO_ADDR_hostname_string(addr
, 1);
422 data
->param_service
= BIO_ADDR_service_string(addr
, 1);
423 BIO_ADDRINFO_free(data
->addr_first
);
424 data
->addr_first
= NULL
;
425 data
->addr_iter
= NULL
;
427 } else if (num
== 3) {
428 data
->connect_family
= *(int *)ptr
;
436 data
->connect_mode
|= BIO_SOCK_NONBLOCK
;
438 data
->connect_mode
&= ~BIO_SOCK_NONBLOCK
;
440 case BIO_C_SET_CONNECT_MODE
:
441 data
->connect_mode
= (int)num
;
452 case BIO_CTRL_GET_CLOSE
:
455 case BIO_CTRL_SET_CLOSE
:
456 b
->shutdown
= (int)num
;
458 case BIO_CTRL_PENDING
:
459 case BIO_CTRL_WPENDING
:
467 if (data
->param_hostname
)
468 BIO_set_conn_hostname(dbio
, data
->param_hostname
);
469 if (data
->param_service
)
470 BIO_set_conn_port(dbio
, data
->param_service
);
471 BIO_set_conn_ip_family(dbio
, data
->connect_family
);
472 BIO_set_conn_mode(dbio
, data
->connect_mode
);
474 * FIXME: the cast of the function seems unlikely to be a good
477 (void)BIO_set_info_callback(dbio
, data
->info_callback
);
480 case BIO_CTRL_SET_CALLBACK
:
481 ret
= 0; /* use callback ctrl */
483 case BIO_CTRL_GET_CALLBACK
:
487 fptr
= (BIO_info_cb
**)ptr
;
488 *fptr
= data
->info_callback
;
498 static long conn_callback_ctrl(BIO
*b
, int cmd
, BIO_info_cb
*fp
)
503 data
= (BIO_CONNECT
*)b
->ptr
;
506 case BIO_CTRL_SET_CALLBACK
:
508 data
->info_callback
= fp
;
518 static int conn_puts(BIO
*bp
, const char *str
)
523 ret
= conn_write(bp
, str
, n
);
527 BIO
*BIO_new_connect(const char *str
)
531 ret
= BIO_new(BIO_s_connect());
534 if (BIO_set_conn_hostname(ret
, str
))