2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (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 int (*info_callback
) (const BIO
*bio
, int state
, int ret
);
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
, /* connect_gets, */
75 static int conn_state(BIO
*b
, BIO_CONNECT
*c
)
78 int (*cb
) (const BIO
*, int, int) = 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(SYS_F_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(SYS_F_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(SYS_F_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
)
228 ret
->state
= BIO_CONN_S_BEFORE
;
229 ret
->connect_family
= BIO_FAMILY_IPANY
;
233 void BIO_CONNECT_free(BIO_CONNECT
*a
)
238 OPENSSL_free(a
->param_hostname
);
239 OPENSSL_free(a
->param_service
);
240 BIO_ADDRINFO_free(a
->addr_first
);
244 const BIO_METHOD
*BIO_s_connect(void)
246 return (&methods_connectp
);
249 static int conn_new(BIO
*bi
)
252 bi
->num
= (int)INVALID_SOCKET
;
254 if ((bi
->ptr
= (char *)BIO_CONNECT_new()) == NULL
)
260 static void conn_close_socket(BIO
*bio
)
264 c
= (BIO_CONNECT
*)bio
->ptr
;
265 if (bio
->num
!= (int)INVALID_SOCKET
) {
266 /* Only do a shutdown if things were established */
267 if (c
->state
== BIO_CONN_S_OK
)
268 shutdown(bio
->num
, 2);
269 BIO_closesocket(bio
->num
);
270 bio
->num
= (int)INVALID_SOCKET
;
274 static int conn_free(BIO
*a
)
280 data
= (BIO_CONNECT
*)a
->ptr
;
283 conn_close_socket(a
);
284 BIO_CONNECT_free(data
);
292 static int conn_read(BIO
*b
, char *out
, int outl
)
297 data
= (BIO_CONNECT
*)b
->ptr
;
298 if (data
->state
!= BIO_CONN_S_OK
) {
299 ret
= conn_state(b
, data
);
305 clear_socket_error();
306 ret
= readsocket(b
->num
, out
, outl
);
307 BIO_clear_retry_flags(b
);
309 if (BIO_sock_should_retry(ret
))
310 BIO_set_retry_read(b
);
316 static int conn_write(BIO
*b
, const char *in
, int inl
)
321 data
= (BIO_CONNECT
*)b
->ptr
;
322 if (data
->state
!= BIO_CONN_S_OK
) {
323 ret
= conn_state(b
, data
);
328 clear_socket_error();
329 ret
= writesocket(b
->num
, in
, inl
);
330 BIO_clear_retry_flags(b
);
332 if (BIO_sock_should_retry(ret
))
333 BIO_set_retry_write(b
);
338 static long conn_ctrl(BIO
*b
, int cmd
, long num
, void *ptr
)
342 const char **pptr
= NULL
;
346 data
= (BIO_CONNECT
*)b
->ptr
;
351 data
->state
= BIO_CONN_S_BEFORE
;
352 conn_close_socket(b
);
353 BIO_ADDRINFO_free(data
->addr_first
);
354 data
->addr_first
= NULL
;
357 case BIO_C_DO_STATE_MACHINE
:
358 /* use this one to start the connection */
359 if (data
->state
!= BIO_CONN_S_OK
)
360 ret
= (long)conn_state(b
, data
);
364 case BIO_C_GET_CONNECT
:
366 pptr
= (const char **)ptr
;
368 *pptr
= data
->param_hostname
;
369 } else if (num
== 1) {
370 *pptr
= data
->param_service
;
371 } else if (num
== 2) {
372 *pptr
= (const char *)BIO_ADDRINFO_address(data
->addr_iter
);
373 } else if (num
== 3) {
374 switch (BIO_ADDRINFO_family(data
->addr_iter
)) {
377 ret
= BIO_FAMILY_IPV6
;
381 ret
= BIO_FAMILY_IPV4
;
384 ret
= data
->connect_family
;
397 case BIO_C_SET_CONNECT
:
401 char *hold_service
= data
->param_service
;
402 /* We affect the hostname regardless. However, the input
403 * string might contain a host:service spec, so we must
404 * parse it, which might or might not affect the service
406 OPENSSL_free(data
->param_hostname
);
407 data
->param_hostname
= NULL
;
408 ret
= BIO_parse_hostserv(ptr
,
409 &data
->param_hostname
,
410 &data
->param_service
,
411 BIO_PARSE_PRIO_HOST
);
412 if (hold_service
!= data
->param_service
)
413 OPENSSL_free(hold_service
);
414 } else if (num
== 1) {
415 OPENSSL_free(data
->param_service
);
416 data
->param_service
= BUF_strdup(ptr
);
417 } else if (num
== 2) {
418 const BIO_ADDR
*addr
= (const BIO_ADDR
*)ptr
;
420 data
->param_hostname
= BIO_ADDR_hostname_string(addr
, 1);
421 data
->param_service
= BIO_ADDR_service_string(addr
, 1);
422 BIO_ADDRINFO_free(data
->addr_first
);
423 data
->addr_first
= NULL
;
424 data
->addr_iter
= NULL
;
426 } else if (num
== 3) {
427 data
->connect_family
= *(int *)ptr
;
435 data
->connect_mode
|= BIO_SOCK_NONBLOCK
;
437 data
->connect_mode
&= ~BIO_SOCK_NONBLOCK
;
439 case BIO_C_SET_CONNECT_MODE
:
440 data
->connect_mode
= (int)num
;
451 case BIO_CTRL_GET_CLOSE
:
454 case BIO_CTRL_SET_CLOSE
:
455 b
->shutdown
= (int)num
;
457 case BIO_CTRL_PENDING
:
458 case BIO_CTRL_WPENDING
:
466 if (data
->param_hostname
)
467 BIO_set_conn_hostname(dbio
, data
->param_hostname
);
468 if (data
->param_service
)
469 BIO_set_conn_port(dbio
, data
->param_service
);
470 BIO_set_conn_ip_family(dbio
, data
->connect_family
);
471 BIO_set_conn_mode(dbio
, data
->connect_mode
);
473 * FIXME: the cast of the function seems unlikely to be a good
476 (void)BIO_set_info_callback(dbio
,
477 (bio_info_cb
*)data
->info_callback
);
480 case BIO_CTRL_SET_CALLBACK
:
481 ret
= 0; /* use callback ctrl */
483 case BIO_CTRL_GET_CALLBACK
:
485 int (**fptr
) (const BIO
*bio
, int state
, int xret
);
487 fptr
= (int (**)(const BIO
*bio
, int state
, int xret
))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
=
509 (int (*)(const struct bio_st
*, int, int))fp
;
519 static int conn_puts(BIO
*bp
, const char *str
)
524 ret
= conn_write(bp
, str
, n
);
528 BIO
*BIO_new_connect(const char *str
)
532 ret
= BIO_new(BIO_s_connect());
535 if (BIO_set_conn_hostname(ret
, str
))