mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
Refactoring BIO: adapt BIO_s_connect and BIO_s_accept
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
This commit is contained in:
parent
4f1374e605
commit
417be660e1
@ -325,9 +325,9 @@ long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
|
||||
return (BIO_ctrl(b, cmd, larg, (char *)&i));
|
||||
}
|
||||
|
||||
char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
|
||||
void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
|
||||
{
|
||||
char *p = NULL;
|
||||
void *p = NULL;
|
||||
|
||||
if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
|
||||
return (NULL);
|
||||
|
@ -57,36 +57,27 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#define USE_SOCKETS
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bio.h>
|
||||
#include "bio_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
|
||||
/*
|
||||
* We are currently using deprecated functions here, and GCC warns
|
||||
* us about them, but since we know, we don't want to hear it.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
|
||||
/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
|
||||
# undef FIONBIO
|
||||
# endif
|
||||
|
||||
typedef struct bio_accept_st {
|
||||
int state;
|
||||
int accept_family;
|
||||
int bind_mode; /* Socket mode for BIO_listen */
|
||||
int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
|
||||
char *param_addr;
|
||||
char *param_serv;
|
||||
|
||||
int accept_sock;
|
||||
int accept_nbio;
|
||||
char *addr;
|
||||
int nbio;
|
||||
/*
|
||||
* If 0, it means normal, if 1, do a connect on bind failure, and if
|
||||
* there is no-one listening, bind with SO_REUSEADDR. If 2, always use
|
||||
* SO_REUSEADDR.
|
||||
*/
|
||||
int bind_mode;
|
||||
|
||||
BIO_ADDRINFO *addr_first;
|
||||
const BIO_ADDRINFO *addr_iter;
|
||||
BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */
|
||||
char *cache_accepting_name, *cache_accepting_serv;
|
||||
BIO_ADDR cache_peer_addr;
|
||||
char *cache_peer_name, *cache_peer_serv;
|
||||
|
||||
BIO *bio_chain;
|
||||
} BIO_ACCEPT;
|
||||
|
||||
@ -102,8 +93,11 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void);
|
||||
static void BIO_ACCEPT_free(BIO_ACCEPT *a);
|
||||
|
||||
# define ACPT_S_BEFORE 1
|
||||
# define ACPT_S_GET_ACCEPT_SOCKET 2
|
||||
# define ACPT_S_OK 3
|
||||
# define ACPT_S_GET_ADDR 2
|
||||
# define ACPT_S_CREATE_SOCKET 3
|
||||
# define ACPT_S_LISTEN 4
|
||||
# define ACPT_S_ACCEPT 5
|
||||
# define ACPT_S_OK 6
|
||||
|
||||
static BIO_METHOD methods_acceptp = {
|
||||
BIO_TYPE_ACCEPT,
|
||||
@ -144,8 +138,8 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void)
|
||||
|
||||
if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
|
||||
return (NULL);
|
||||
ret->accept_family = BIO_FAMILY_IPANY;
|
||||
ret->accept_sock = (int)INVALID_SOCKET;
|
||||
ret->bind_mode = BIO_BIND_NORMAL;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -155,7 +149,12 @@ static void BIO_ACCEPT_free(BIO_ACCEPT *a)
|
||||
return;
|
||||
|
||||
OPENSSL_free(a->param_addr);
|
||||
OPENSSL_free(a->addr);
|
||||
OPENSSL_free(a->param_serv);
|
||||
BIO_ADDRINFO_free(a->addr_first);
|
||||
OPENSSL_free(a->cache_accepting_name);
|
||||
OPENSSL_free(a->cache_accepting_serv);
|
||||
OPENSSL_free(a->cache_peer_name);
|
||||
OPENSSL_free(a->cache_peer_serv);
|
||||
BIO_free(a->bio_chain);
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
@ -194,102 +193,203 @@ static int acpt_free(BIO *a)
|
||||
static int acpt_state(BIO *b, BIO_ACCEPT *c)
|
||||
{
|
||||
BIO *bio = NULL, *dbio;
|
||||
int s = -1;
|
||||
int i;
|
||||
int s = -1, ret = -1;
|
||||
|
||||
again:
|
||||
switch (c->state) {
|
||||
case ACPT_S_BEFORE:
|
||||
if (c->param_addr == NULL) {
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED);
|
||||
return (-1);
|
||||
}
|
||||
s = BIO_get_accept_socket(c->param_addr, c->bind_mode);
|
||||
if (s == (int)INVALID_SOCKET)
|
||||
return (-1);
|
||||
|
||||
if (c->accept_nbio) {
|
||||
if (!BIO_socket_nbio(s, 1)) {
|
||||
closesocket(s);
|
||||
BIOerr(BIO_F_ACPT_STATE,
|
||||
BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
|
||||
return (-1);
|
||||
for (;;) {
|
||||
switch (c->state) {
|
||||
case ACPT_S_BEFORE:
|
||||
if (c->param_addr == NULL && c->param_serv == NULL) {
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED);
|
||||
ERR_add_error_data(4,
|
||||
"hostname=", c->param_addr,
|
||||
" service=", c->param_serv);
|
||||
goto exit_loop;
|
||||
}
|
||||
}
|
||||
c->accept_sock = s;
|
||||
b->num = s;
|
||||
c->state = ACPT_S_GET_ACCEPT_SOCKET;
|
||||
return (1);
|
||||
/* break; */
|
||||
case ACPT_S_GET_ACCEPT_SOCKET:
|
||||
if (b->next_bio != NULL) {
|
||||
|
||||
/* Because we're starting a new bind, any cached name and serv
|
||||
* are now obsolete and need to be cleaned out.
|
||||
* QUESTION: should this be done in acpt_close_socket() instead?
|
||||
*/
|
||||
OPENSSL_free(c->cache_accepting_name);
|
||||
c->cache_accepting_name = NULL;
|
||||
OPENSSL_free(c->cache_accepting_serv);
|
||||
c->cache_accepting_serv = NULL;
|
||||
OPENSSL_free(c->cache_peer_name);
|
||||
c->cache_peer_name = NULL;
|
||||
OPENSSL_free(c->cache_peer_serv);
|
||||
c->cache_peer_serv = NULL;
|
||||
|
||||
c->state = ACPT_S_GET_ADDR;
|
||||
break;
|
||||
|
||||
case ACPT_S_GET_ADDR:
|
||||
{
|
||||
int family = AF_UNSPEC;
|
||||
switch (c->accept_family) {
|
||||
case BIO_FAMILY_IPV6:
|
||||
if (1) { /* This is a trick we use to avoid bit rot.
|
||||
* at least the "else" part will always be
|
||||
* compiled.
|
||||
*/
|
||||
#ifdef AF_INET6
|
||||
family = AF_INET6;
|
||||
} else {
|
||||
#endif
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
|
||||
goto exit_loop;
|
||||
}
|
||||
break;
|
||||
case BIO_FAMILY_IPV4:
|
||||
family = AF_INET;
|
||||
break;
|
||||
case BIO_FAMILY_IPANY:
|
||||
family = AF_UNSPEC;
|
||||
break;
|
||||
default:
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
|
||||
goto exit_loop;
|
||||
}
|
||||
if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER,
|
||||
family, SOCK_STREAM, &c->addr_first) == 0)
|
||||
goto exit_loop;
|
||||
}
|
||||
if (c->addr_first == NULL) {
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
|
||||
goto exit_loop;
|
||||
}
|
||||
/* We're currently not iterating, but set this as preparation
|
||||
* for possible future development in that regard
|
||||
*/
|
||||
c->addr_iter = c->addr_first;
|
||||
c->state = ACPT_S_CREATE_SOCKET;
|
||||
break;
|
||||
|
||||
case ACPT_S_CREATE_SOCKET:
|
||||
ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
|
||||
BIO_ADDRINFO_socktype(c->addr_iter),
|
||||
BIO_ADDRINFO_protocol(c->addr_iter), 0);
|
||||
if (ret == (int)INVALID_SOCKET) {
|
||||
SYSerr(SYS_F_SOCKET, get_last_socket_error());
|
||||
ERR_add_error_data(4,
|
||||
"hostname=", c->param_addr,
|
||||
" service=", c->param_serv);
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
|
||||
goto exit_loop;
|
||||
}
|
||||
c->accept_sock = ret;
|
||||
b->num = ret;
|
||||
c->state = ACPT_S_LISTEN;
|
||||
break;
|
||||
|
||||
case ACPT_S_LISTEN:
|
||||
{
|
||||
if (!BIO_listen(c->accept_sock,
|
||||
BIO_ADDRINFO_address(c->addr_iter),
|
||||
c->bind_mode)) {
|
||||
BIO_closesocket(c->accept_sock);
|
||||
goto exit_loop;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
union BIO_sock_info_u info;
|
||||
|
||||
info.addr = &c->cache_accepting_addr;
|
||||
if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS,
|
||||
&info)) {
|
||||
BIO_closesocket(c->accept_sock);
|
||||
goto exit_loop;
|
||||
}
|
||||
}
|
||||
|
||||
c->cache_accepting_name =
|
||||
BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
|
||||
c->cache_accepting_serv =
|
||||
BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
|
||||
c->state = ACPT_S_ACCEPT;
|
||||
s = -1;
|
||||
ret = 1;
|
||||
goto end;
|
||||
|
||||
case ACPT_S_ACCEPT:
|
||||
if (b->next_bio != NULL) {
|
||||
c->state = ACPT_S_OK;
|
||||
break;
|
||||
}
|
||||
BIO_clear_retry_flags(b);
|
||||
b->retry_reason = 0;
|
||||
|
||||
s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr,
|
||||
c->accepted_mode);
|
||||
|
||||
/* If the returned socket is invalid, this might still be
|
||||
* retryable
|
||||
*/
|
||||
if (s < 0) {
|
||||
if (BIO_sock_should_retry(s)) {
|
||||
BIO_set_retry_special(b);
|
||||
b->retry_reason = BIO_RR_ACCEPT;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* If it wasn't retryable, we fail */
|
||||
if (s < 0) {
|
||||
ret = s;
|
||||
goto exit_loop;
|
||||
}
|
||||
|
||||
bio = BIO_new_socket(s, BIO_CLOSE);
|
||||
if (bio == NULL)
|
||||
goto exit_loop;
|
||||
|
||||
BIO_set_callback(bio, BIO_get_callback(b));
|
||||
BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
|
||||
|
||||
/*
|
||||
* If the accept BIO has an bio_chain, we dup it and put the new
|
||||
* socket at the end.
|
||||
*/
|
||||
if (c->bio_chain != NULL) {
|
||||
if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
|
||||
goto exit_loop;
|
||||
if (!BIO_push(dbio, bio))
|
||||
goto exit_loop;
|
||||
bio = dbio;
|
||||
}
|
||||
if (BIO_push(b, bio) == NULL)
|
||||
goto exit_loop;
|
||||
|
||||
c->cache_peer_name =
|
||||
BIO_ADDR_hostname_string(&c->cache_peer_addr, 1);
|
||||
c->cache_peer_serv =
|
||||
BIO_ADDR_service_string(&c->cache_peer_addr, 1);
|
||||
c->state = ACPT_S_OK;
|
||||
goto again;
|
||||
}
|
||||
BIO_clear_retry_flags(b);
|
||||
b->retry_reason = 0;
|
||||
i = BIO_accept(c->accept_sock, &(c->addr));
|
||||
bio = NULL;
|
||||
ret = 1;
|
||||
goto end;
|
||||
|
||||
/* -2 return means we should retry */
|
||||
if (i == -2) {
|
||||
BIO_set_retry_special(b);
|
||||
b->retry_reason = BIO_RR_ACCEPT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
return (i);
|
||||
|
||||
bio = BIO_new_socket(i, BIO_CLOSE);
|
||||
if (bio == NULL)
|
||||
goto err;
|
||||
|
||||
BIO_set_callback(bio, BIO_get_callback(b));
|
||||
BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
|
||||
|
||||
if (c->nbio) {
|
||||
if (!BIO_socket_nbio(i, 1)) {
|
||||
BIOerr(BIO_F_ACPT_STATE,
|
||||
BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
|
||||
goto err;
|
||||
case ACPT_S_OK:
|
||||
if (b->next_bio == NULL) {
|
||||
c->state = ACPT_S_ACCEPT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* If the accept BIO has an bio_chain, we dup it and put the new
|
||||
* socket at the end.
|
||||
*/
|
||||
if (c->bio_chain != NULL) {
|
||||
if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
|
||||
goto err;
|
||||
if (!BIO_push(dbio, bio))
|
||||
goto err;
|
||||
bio = dbio;
|
||||
default:
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if (BIO_push(b, bio) == NULL)
|
||||
goto err;
|
||||
|
||||
c->state = ACPT_S_OK;
|
||||
return (1);
|
||||
err:
|
||||
if (bio != NULL)
|
||||
BIO_free(bio);
|
||||
else if (s >= 0)
|
||||
closesocket(s);
|
||||
return (0);
|
||||
/* break; */
|
||||
case ACPT_S_OK:
|
||||
if (b->next_bio == NULL) {
|
||||
c->state = ACPT_S_GET_ACCEPT_SOCKET;
|
||||
goto again;
|
||||
}
|
||||
return (1);
|
||||
/* break; */
|
||||
default:
|
||||
return (0);
|
||||
/* break; */
|
||||
}
|
||||
|
||||
exit_loop:
|
||||
if (bio != NULL)
|
||||
BIO_free(bio);
|
||||
else if (s >= 0)
|
||||
BIO_closesocket(s);
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int acpt_read(BIO *b, char *out, int outl)
|
||||
@ -344,6 +444,8 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
ret = 0;
|
||||
data->state = ACPT_S_BEFORE;
|
||||
acpt_close_socket(b);
|
||||
BIO_ADDRINFO_free(data->addr_first);
|
||||
data->addr_first = NULL;
|
||||
b->flags = 0;
|
||||
break;
|
||||
case BIO_C_DO_STATE_MACHINE:
|
||||
@ -353,25 +455,48 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
case BIO_C_SET_ACCEPT:
|
||||
if (ptr != NULL) {
|
||||
if (num == 0) {
|
||||
b->init = 1;
|
||||
char *hold_serv = data->param_serv;
|
||||
/* We affect the hostname regardless. However, the input
|
||||
* string might contain a host:service spec, so we must
|
||||
* parse it, which might or might not affect the service
|
||||
*/
|
||||
OPENSSL_free(data->param_addr);
|
||||
data->param_addr = OPENSSL_strdup(ptr);
|
||||
data->param_addr = NULL;
|
||||
ret = BIO_parse_hostserv(ptr,
|
||||
&data->param_addr,
|
||||
&data->param_serv,
|
||||
BIO_PARSE_PRIO_SERV);
|
||||
if (hold_serv != data->param_serv)
|
||||
OPENSSL_free(hold_serv);
|
||||
b->init = 1;
|
||||
} else if (num == 1) {
|
||||
data->accept_nbio = (ptr != NULL);
|
||||
OPENSSL_free(data->param_serv);
|
||||
data->param_serv = BUF_strdup(ptr);
|
||||
b->init = 1;
|
||||
} else if (num == 2) {
|
||||
if (ptr != NULL)
|
||||
data->bind_mode |= BIO_SOCK_NONBLOCK;
|
||||
else
|
||||
data->bind_mode &= ~BIO_SOCK_NONBLOCK;
|
||||
} else if (num == 3) {
|
||||
BIO_free(data->bio_chain);
|
||||
data->bio_chain = (BIO *)ptr;
|
||||
} else if (num == 4) {
|
||||
data->accept_family = *(int *)ptr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIO_C_SET_NBIO:
|
||||
data->nbio = (int)num;
|
||||
if (num != 0)
|
||||
data->accepted_mode |= BIO_SOCK_NONBLOCK;
|
||||
else
|
||||
data->accepted_mode &= ~BIO_SOCK_NONBLOCK;
|
||||
break;
|
||||
case BIO_C_SET_FD:
|
||||
b->init = 1;
|
||||
b->num = *((int *)ptr);
|
||||
data->accept_sock = b->num;
|
||||
data->state = ACPT_S_GET_ACCEPT_SOCKET;
|
||||
data->state = ACPT_S_ACCEPT;
|
||||
b->shutdown = (int)num;
|
||||
b->init = 1;
|
||||
break;
|
||||
@ -386,9 +511,35 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
break;
|
||||
case BIO_C_GET_ACCEPT:
|
||||
if (b->init) {
|
||||
if (ptr != NULL) {
|
||||
if (num == 0 && ptr != NULL) {
|
||||
pp = (char **)ptr;
|
||||
*pp = data->param_addr;
|
||||
*pp = data->cache_accepting_name;
|
||||
} else if (num == 1 && ptr != NULL) {
|
||||
pp = (char **)ptr;
|
||||
*pp = data->cache_accepting_serv;
|
||||
} else if (num == 2 && ptr != NULL) {
|
||||
pp = (char **)ptr;
|
||||
*pp = data->cache_peer_name;
|
||||
} else if (num == 3 && ptr != NULL) {
|
||||
pp = (char **)ptr;
|
||||
*pp = data->cache_peer_serv;
|
||||
} else if (num == 4) {
|
||||
switch (BIO_ADDRINFO_family(data->addr_iter)) {
|
||||
#ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
ret = BIO_FAMILY_IPV6;
|
||||
break;
|
||||
#endif
|
||||
case AF_INET:
|
||||
ret = BIO_FAMILY_IPV4;
|
||||
break;
|
||||
case 0:
|
||||
ret = data->accept_family;
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ret = -1;
|
||||
} else
|
||||
|
@ -57,31 +57,20 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#define USE_SOCKETS
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include "bio_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
|
||||
/*
|
||||
* We are currently using deprecated functions here, and GCC warns
|
||||
* us about them, but since we know, we don't want to hear it.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
|
||||
/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
|
||||
# undef FIONBIO
|
||||
# endif
|
||||
|
||||
typedef struct bio_connect_st {
|
||||
int state;
|
||||
int connect_family;
|
||||
char *param_hostname;
|
||||
char *param_port;
|
||||
int nbio;
|
||||
unsigned char ip[4];
|
||||
unsigned short port;
|
||||
struct sockaddr_in them;
|
||||
char *param_service;
|
||||
int connect_mode;
|
||||
|
||||
BIO_ADDRINFO *addr_first;
|
||||
const BIO_ADDRINFO *addr_iter;
|
||||
/*
|
||||
* int socket; this will be kept in bio->num so that it is compatible
|
||||
* with the bss_sock bio
|
||||
@ -107,6 +96,13 @@ static void conn_close_socket(BIO *data);
|
||||
BIO_CONNECT *BIO_CONNECT_new(void);
|
||||
void BIO_CONNECT_free(BIO_CONNECT *a);
|
||||
|
||||
#define BIO_CONN_S_BEFORE 1
|
||||
#define BIO_CONN_S_GET_ADDR 2
|
||||
#define BIO_CONN_S_CREATE_SOCKET 3
|
||||
#define BIO_CONN_S_CONNECT 4
|
||||
#define BIO_CONN_S_OK 5
|
||||
#define BIO_CONN_S_BLOCKED_CONNECT 6
|
||||
|
||||
static BIO_METHOD methods_connectp = {
|
||||
BIO_TYPE_CONNECT,
|
||||
"socket connect",
|
||||
@ -123,8 +119,6 @@ static BIO_METHOD methods_connectp = {
|
||||
static int conn_state(BIO *b, BIO_CONNECT *c)
|
||||
{
|
||||
int ret = -1, i;
|
||||
unsigned long l;
|
||||
char *p, *q;
|
||||
int (*cb) (const BIO *, int, int) = NULL;
|
||||
|
||||
if (c->info_callback != NULL)
|
||||
@ -133,122 +127,103 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
|
||||
for (;;) {
|
||||
switch (c->state) {
|
||||
case BIO_CONN_S_BEFORE:
|
||||
p = c->param_hostname;
|
||||
if (p == NULL) {
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_SPECIFIED);
|
||||
if (c->param_hostname == NULL && c->param_service == NULL) {
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
|
||||
ERR_add_error_data(4,
|
||||
"hostname=", c->param_hostname,
|
||||
" service=", c->param_service);
|
||||
goto exit_loop;
|
||||
}
|
||||
for (; *p != '\0'; p++) {
|
||||
if ((*p == ':') || (*p == '/'))
|
||||
c->state = BIO_CONN_S_GET_ADDR;
|
||||
break;
|
||||
|
||||
case BIO_CONN_S_GET_ADDR:
|
||||
{
|
||||
int family = AF_UNSPEC;
|
||||
switch (c->connect_family) {
|
||||
case BIO_FAMILY_IPV6:
|
||||
if (1) { /* This is a trick we use to avoid bit rot.
|
||||
* at least the "else" part will always be
|
||||
* compiled.
|
||||
*/
|
||||
#ifdef AF_INET6
|
||||
family = AF_INET6;
|
||||
} else {
|
||||
#endif
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
|
||||
goto exit_loop;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
i = *p;
|
||||
if ((i == ':') || (i == '/')) {
|
||||
|
||||
*(p++) = '\0';
|
||||
if (i == ':') {
|
||||
for (q = p; *q; q++)
|
||||
if (*q == '/') {
|
||||
*q = '\0';
|
||||
break;
|
||||
}
|
||||
OPENSSL_free(c->param_port);
|
||||
c->param_port = OPENSSL_strdup(p);
|
||||
case BIO_FAMILY_IPV4:
|
||||
family = AF_INET;
|
||||
break;
|
||||
case BIO_FAMILY_IPANY:
|
||||
family = AF_UNSPEC;
|
||||
break;
|
||||
default:
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
|
||||
goto exit_loop;
|
||||
}
|
||||
if (BIO_lookup(c->param_hostname, c->param_service,
|
||||
BIO_LOOKUP_CLIENT,
|
||||
family, SOCK_STREAM, &c->addr_first) == 0)
|
||||
goto exit_loop;
|
||||
}
|
||||
|
||||
if (c->param_port == NULL) {
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_NO_PORT_SPECIFIED);
|
||||
ERR_add_error_data(2, "host=", c->param_hostname);
|
||||
if (c->addr_first == NULL) {
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
|
||||
goto exit_loop;
|
||||
}
|
||||
c->state = BIO_CONN_S_GET_IP;
|
||||
break;
|
||||
|
||||
case BIO_CONN_S_GET_IP:
|
||||
if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0)
|
||||
goto exit_loop;
|
||||
c->state = BIO_CONN_S_GET_PORT;
|
||||
break;
|
||||
|
||||
case BIO_CONN_S_GET_PORT:
|
||||
if (c->param_port == NULL) {
|
||||
/* abort(); */
|
||||
goto exit_loop;
|
||||
} else if (BIO_get_port(c->param_port, &c->port) <= 0)
|
||||
goto exit_loop;
|
||||
c->addr_iter = c->addr_first;
|
||||
c->state = BIO_CONN_S_CREATE_SOCKET;
|
||||
break;
|
||||
|
||||
case BIO_CONN_S_CREATE_SOCKET:
|
||||
/* now setup address */
|
||||
memset(&c->them, 0, sizeof(c->them));
|
||||
c->them.sin_family = AF_INET;
|
||||
c->them.sin_port = htons((unsigned short)c->port);
|
||||
l = (unsigned long)
|
||||
((unsigned long)c->ip[0] << 24L) |
|
||||
((unsigned long)c->ip[1] << 16L) |
|
||||
((unsigned long)c->ip[2] << 8L) | ((unsigned long)c->ip[3]);
|
||||
c->them.sin_addr.s_addr = htonl(l);
|
||||
c->state = BIO_CONN_S_CREATE_SOCKET;
|
||||
|
||||
ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
|
||||
BIO_ADDRINFO_socktype(c->addr_iter),
|
||||
BIO_ADDRINFO_protocol(c->addr_iter), 0);
|
||||
if (ret == (int)INVALID_SOCKET) {
|
||||
SYSerr(SYS_F_SOCKET, get_last_socket_error());
|
||||
ERR_add_error_data(4, "host=", c->param_hostname,
|
||||
":", c->param_port);
|
||||
ERR_add_error_data(4,
|
||||
"hostname=", c->param_hostname,
|
||||
" service=", c->param_service);
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
|
||||
goto exit_loop;
|
||||
}
|
||||
b->num = ret;
|
||||
c->state = BIO_CONN_S_NBIO;
|
||||
break;
|
||||
|
||||
case BIO_CONN_S_NBIO:
|
||||
if (c->nbio) {
|
||||
if (!BIO_socket_nbio(b->num, 1)) {
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_ERROR_SETTING_NBIO);
|
||||
ERR_add_error_data(4, "host=",
|
||||
c->param_hostname, ":", c->param_port);
|
||||
goto exit_loop;
|
||||
}
|
||||
}
|
||||
c->state = BIO_CONN_S_CONNECT;
|
||||
|
||||
# if defined(SO_KEEPALIVE)
|
||||
i = 1;
|
||||
i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
|
||||
sizeof(i));
|
||||
if (i < 0) {
|
||||
SYSerr(SYS_F_SOCKET, get_last_socket_error());
|
||||
ERR_add_error_data(4, "host=", c->param_hostname,
|
||||
":", c->param_port);
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_KEEPALIVE);
|
||||
goto exit_loop;
|
||||
}
|
||||
# endif
|
||||
break;
|
||||
|
||||
case BIO_CONN_S_CONNECT:
|
||||
BIO_clear_retry_flags(b);
|
||||
ret = connect(b->num,
|
||||
(struct sockaddr *)&c->them, sizeof(c->them));
|
||||
ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
|
||||
BIO_SOCK_KEEPALIVE | c->connect_mode);
|
||||
b->retry_reason = 0;
|
||||
if (ret < 0) {
|
||||
if (BIO_sock_should_retry(ret)) {
|
||||
BIO_set_retry_special(b);
|
||||
c->state = BIO_CONN_S_BLOCKED_CONNECT;
|
||||
b->retry_reason = BIO_RR_CONNECT;
|
||||
ERR_clear_error();
|
||||
} else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
|
||||
!= NULL) {
|
||||
/*
|
||||
* if there are more addresses to try, do that first
|
||||
*/
|
||||
BIO_closesocket(b->num);
|
||||
c->state = BIO_CONN_S_CREATE_SOCKET;
|
||||
ERR_clear_error();
|
||||
break;
|
||||
} else {
|
||||
SYSerr(SYS_F_CONNECT, get_last_socket_error());
|
||||
ERR_add_error_data(4, "host=",
|
||||
c->param_hostname, ":", c->param_port);
|
||||
ERR_add_error_data(4,
|
||||
"hostname=", c->param_hostname,
|
||||
" service=", c->param_service);
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
|
||||
}
|
||||
goto exit_loop;
|
||||
} else
|
||||
} else {
|
||||
c->state = BIO_CONN_S_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case BIO_CONN_S_BLOCKED_CONNECT:
|
||||
@ -256,8 +231,9 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
|
||||
if (i) {
|
||||
BIO_clear_retry_flags(b);
|
||||
SYSerr(SYS_F_CONNECT, i);
|
||||
ERR_add_error_data(4, "host=",
|
||||
c->param_hostname, ":", c->param_port);
|
||||
ERR_add_error_data(4,
|
||||
"hostname=", c->param_hostname,
|
||||
" service=", c->param_service);
|
||||
BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
|
||||
ret = 0;
|
||||
goto exit_loop;
|
||||
@ -294,9 +270,13 @@ BIO_CONNECT *BIO_CONNECT_new(void)
|
||||
if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
|
||||
return (NULL);
|
||||
ret->state = BIO_CONN_S_BEFORE;
|
||||
ret->connect_family = BIO_FAMILY_IPANY;
|
||||
ret->param_hostname = NULL;
|
||||
ret->param_port = NULL;
|
||||
ret->param_service = NULL;
|
||||
ret->info_callback = NULL;
|
||||
ret->connect_mode = 0;
|
||||
ret->addr_first = NULL;
|
||||
ret->addr_iter = NULL;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -306,7 +286,8 @@ void BIO_CONNECT_free(BIO_CONNECT *a)
|
||||
return;
|
||||
|
||||
OPENSSL_free(a->param_hostname);
|
||||
OPENSSL_free(a->param_port);
|
||||
OPENSSL_free(a->param_service);
|
||||
BIO_ADDRINFO_free(a->addr_first);
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
|
||||
@ -335,7 +316,7 @@ static void conn_close_socket(BIO *bio)
|
||||
/* Only do a shutdown if things were established */
|
||||
if (c->state == BIO_CONN_S_OK)
|
||||
shutdown(bio->num, 2);
|
||||
closesocket(bio->num);
|
||||
BIO_closesocket(bio->num);
|
||||
bio->num = (int)INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
@ -419,6 +400,8 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
ret = 0;
|
||||
data->state = BIO_CONN_S_BEFORE;
|
||||
conn_close_socket(b);
|
||||
BIO_ADDRINFO_free(data->addr_first);
|
||||
data->addr_first = NULL;
|
||||
b->flags = 0;
|
||||
break;
|
||||
case BIO_C_DO_STATE_MACHINE:
|
||||
@ -431,27 +414,33 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
case BIO_C_GET_CONNECT:
|
||||
if (ptr != NULL) {
|
||||
pptr = (const char **)ptr;
|
||||
}
|
||||
|
||||
if (b->init) {
|
||||
if (pptr != NULL) {
|
||||
ret = 1;
|
||||
if (num == 0) {
|
||||
*pptr = data->param_hostname;
|
||||
} else if (num == 1) {
|
||||
*pptr = data->param_port;
|
||||
} else if (num == 2) {
|
||||
*pptr = (char *)&(data->ip[0]);
|
||||
} else {
|
||||
ret = 0;
|
||||
if (num == 0) {
|
||||
*pptr = data->param_hostname;
|
||||
} else if (num == 1) {
|
||||
*pptr = data->param_service;
|
||||
} else if (num == 2) {
|
||||
*pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
|
||||
} else if (num == 3) {
|
||||
switch (BIO_ADDRINFO_family(data->addr_iter)) {
|
||||
# ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
ret = BIO_FAMILY_IPV6;
|
||||
break;
|
||||
# endif
|
||||
case AF_INET:
|
||||
ret = BIO_FAMILY_IPV4;
|
||||
break;
|
||||
case 0:
|
||||
ret = data->connect_family;
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num == 3) {
|
||||
ret = data->port;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
if (pptr != NULL)
|
||||
*pptr = "not initialized";
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
@ -459,32 +448,46 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
if (ptr != NULL) {
|
||||
b->init = 1;
|
||||
if (num == 0) {
|
||||
char *hold_service = data->param_service;
|
||||
/* We affect the hostname regardless. However, the input
|
||||
* string might contain a host:service spec, so we must
|
||||
* parse it, which might or might not affect the service
|
||||
*/
|
||||
OPENSSL_free(data->param_hostname);
|
||||
data->param_hostname = OPENSSL_strdup(ptr);
|
||||
data->param_hostname = NULL;
|
||||
ret = BIO_parse_hostserv(ptr,
|
||||
&data->param_hostname,
|
||||
&data->param_service,
|
||||
BIO_PARSE_PRIO_HOST);
|
||||
if (hold_service != data->param_service)
|
||||
OPENSSL_free(hold_service);
|
||||
} else if (num == 1) {
|
||||
OPENSSL_free(data->param_port);
|
||||
data->param_port = OPENSSL_strdup(ptr);
|
||||
OPENSSL_free(data->param_service);
|
||||
data->param_service = BUF_strdup(ptr);
|
||||
} else if (num == 2) {
|
||||
char buf[16];
|
||||
unsigned char *p = ptr;
|
||||
|
||||
BIO_snprintf(buf, sizeof buf, "%d.%d.%d.%d",
|
||||
p[0], p[1], p[2], p[3]);
|
||||
OPENSSL_free(data->param_hostname);
|
||||
data->param_hostname = OPENSSL_strdup(buf);
|
||||
memcpy(&(data->ip[0]), ptr, 4);
|
||||
const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
|
||||
if (ret) {
|
||||
data->param_hostname = BIO_ADDR_hostname_string(addr, 1);
|
||||
data->param_service = BIO_ADDR_service_string(addr, 1);
|
||||
BIO_ADDRINFO_free(data->addr_first);
|
||||
data->addr_first = NULL;
|
||||
data->addr_iter = NULL;
|
||||
}
|
||||
} else if (num == 3) {
|
||||
char buf[DECIMAL_SIZE(int) + 1];
|
||||
|
||||
BIO_snprintf(buf, sizeof buf, "%d", *(int *)ptr);
|
||||
OPENSSL_free(data->param_port);
|
||||
data->param_port = OPENSSL_strdup(buf);
|
||||
data->port = *(int *)ptr;
|
||||
data->connect_family = *(int *)ptr;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BIO_C_SET_NBIO:
|
||||
data->nbio = (int)num;
|
||||
if (num != 0)
|
||||
data->connect_mode |= BIO_SOCK_NONBLOCK;
|
||||
else
|
||||
data->connect_mode &= ~BIO_SOCK_NONBLOCK;
|
||||
break;
|
||||
case BIO_C_SET_CONNECT_MODE:
|
||||
data->connect_mode = (int)num;
|
||||
break;
|
||||
case BIO_C_GET_FD:
|
||||
if (b->init) {
|
||||
@ -510,11 +513,12 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
case BIO_CTRL_DUP:
|
||||
{
|
||||
dbio = (BIO *)ptr;
|
||||
if (data->param_port)
|
||||
BIO_set_conn_port(dbio, data->param_port);
|
||||
if (data->param_hostname)
|
||||
BIO_set_conn_hostname(dbio, data->param_hostname);
|
||||
BIO_set_nbio(dbio, data->nbio);
|
||||
if (data->param_service)
|
||||
BIO_set_conn_port(dbio, data->param_service);
|
||||
BIO_set_conn_ip_family(dbio, data->connect_family);
|
||||
BIO_set_conn_mode(dbio, data->connect_mode);
|
||||
/*
|
||||
* FIXME: the cast of the function seems unlikely to be a good
|
||||
* idea
|
||||
|
@ -169,7 +169,8 @@ unencrypted example in L<BIO_s_connect(3)>.
|
||||
|
||||
/* We might want to do other things with ssl here */
|
||||
|
||||
BIO_set_conn_hostname(sbio, "localhost:https");
|
||||
/* An empty host part means the loopback address */
|
||||
BIO_set_conn_hostname(sbio, ":https");
|
||||
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
if(BIO_do_connect(sbio) <= 0) {
|
||||
|
@ -59,11 +59,12 @@ the accept socket. See L<BIO_s_fd(3)>
|
||||
BIO_set_accept_port() uses the string B<name> to set the accept
|
||||
port. The port is represented as a string of the form "host:port",
|
||||
where "host" is the interface to use and "port" is the port.
|
||||
The host can be "*" which is interpreted as meaning
|
||||
any interface; "port" has the same syntax
|
||||
as the port specified in BIO_set_conn_port() for connect BIOs,
|
||||
that is it can be a numerical port string or a string to lookup
|
||||
using getservbyname() and a string table.
|
||||
The host can be "*" or empty which is interpreted as meaning
|
||||
any interface. If the host is a IPv6 address, it has to be
|
||||
enclosed in brackets, for example "[::1]:https". "port" has the
|
||||
same syntax as the port specified in BIO_set_conn_port() for
|
||||
connect BIOs, that is it can be a numerical port string or a
|
||||
string to lookup using getservbyname() and a string table.
|
||||
|
||||
BIO_new_accept() combines BIO_new() and BIO_set_accept_port() into
|
||||
a single call: that is it creates a new accept BIO with port
|
||||
|
@ -17,12 +17,10 @@ BIO_set_nbio, BIO_do_connect - connect BIO
|
||||
|
||||
long BIO_set_conn_hostname(BIO *b, char *name);
|
||||
long BIO_set_conn_port(BIO *b, char *port);
|
||||
long BIO_set_conn_ip(BIO *b, char *ip);
|
||||
long BIO_set_conn_int_port(BIO *b, char *port);
|
||||
char *BIO_get_conn_hostname(BIO *b);
|
||||
char *BIO_get_conn_port(BIO *b);
|
||||
char *BIO_get_conn_ip(BIO *b);
|
||||
long BIO_get_conn_int_port(BIO *b);
|
||||
long BIO_set_conn_address(BIO *b, BIO_ADDR *addr);
|
||||
const char *BIO_get_conn_hostname(BIO *b);
|
||||
const char *BIO_get_conn_port(BIO *b);
|
||||
const BIO_ADDR *BIO_get_conn_address(BIO *b);
|
||||
|
||||
long BIO_set_nbio(BIO *b, long n);
|
||||
|
||||
@ -57,9 +55,9 @@ it also returns the socket . If B<c> is not NULL it should be of
|
||||
type (int *).
|
||||
|
||||
BIO_set_conn_hostname() uses the string B<name> to set the hostname.
|
||||
The hostname can be an IP address. The hostname can also include the
|
||||
port in the form hostname:port . It is also acceptable to use the
|
||||
form "hostname/any/other/path" or "hostname:port/any/other/path".
|
||||
The hostname can be an IP address; if the address is a IPv6 one, it
|
||||
must be enclosed with brackets. The hostname can also include the
|
||||
port in the form hostname:port.
|
||||
|
||||
BIO_set_conn_port() sets the port to B<port>. B<port> can be the
|
||||
numerical form or a string such as "http". A string will be looked
|
||||
@ -67,21 +65,18 @@ up first using getservbyname() on the host platform but if that
|
||||
fails a standard table of port names will be used. This internal
|
||||
list is http, telnet, socks, https, ssl, ftp, and gopher.
|
||||
|
||||
BIO_set_conn_ip() sets the IP address to B<ip> using binary form,
|
||||
that is four bytes specifying the IP address in big-endian form.
|
||||
|
||||
BIO_set_conn_int_port() sets the port using B<port>. B<port> should
|
||||
be of type (int *).
|
||||
BIO_set_conn_address() sets the address and port information using
|
||||
a BIO_ADDR(3ssl).
|
||||
|
||||
BIO_get_conn_hostname() returns the hostname of the connect BIO or
|
||||
NULL if the BIO is initialized but no hostname is set.
|
||||
This return value is an internal pointer which should not be modified.
|
||||
|
||||
BIO_get_conn_port() returns the port as a string.
|
||||
This return value is an internal pointer which should not be modified.
|
||||
|
||||
BIO_get_conn_ip() returns the IP address in binary form.
|
||||
|
||||
BIO_get_conn_int_port() returns the port as an int.
|
||||
BIO_get_conn_address() returns the address information as a BIO_ADDR.
|
||||
This return value is an internal pointer which should not be modified.
|
||||
|
||||
BIO_set_nbio() sets the non blocking I/O flag to B<n>. If B<n> is
|
||||
zero then blocking I/O is set. If B<n> is 1 then non blocking I/O
|
||||
@ -189,4 +184,4 @@ to retrieve a page and copy the result to standard output.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
TBA
|
||||
L<BIO_ADDR(3)>
|
||||
|
@ -382,15 +382,6 @@ struct bio_dgram_sctp_prinfo {
|
||||
};
|
||||
# endif
|
||||
|
||||
/* connect BIO stuff */
|
||||
# define BIO_CONN_S_BEFORE 1
|
||||
# define BIO_CONN_S_GET_IP 2
|
||||
# define BIO_CONN_S_GET_PORT 3
|
||||
# define BIO_CONN_S_CREATE_SOCKET 4
|
||||
# define BIO_CONN_S_CONNECT 5
|
||||
# define BIO_CONN_S_OK 6
|
||||
# define BIO_CONN_S_BLOCKED_CONNECT 7
|
||||
# define BIO_CONN_S_NBIO 8
|
||||
/*
|
||||
* #define BIO_CONN_get_param_hostname BIO_ctrl
|
||||
*/
|
||||
@ -455,31 +446,47 @@ struct bio_dgram_sctp_prinfo {
|
||||
# define BIO_C_SET_EX_ARG 153
|
||||
# define BIO_C_GET_EX_ARG 154
|
||||
|
||||
# define BIO_C_SET_CONNECT_MODE 155
|
||||
|
||||
# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg)
|
||||
# define BIO_get_app_data(s) BIO_get_ex_data(s,0)
|
||||
|
||||
/* BIO_s_connect() and BIO_s_socks4a_connect() */
|
||||
# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
|
||||
# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
|
||||
# define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
|
||||
# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
|
||||
# define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
|
||||
# define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
|
||||
# define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
|
||||
# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL)
|
||||
/* IP families we support, for BIO_s_connect() and BIO_s_accept() */
|
||||
/* Note: the underlying operating system may not support some of them */
|
||||
# define BIO_FAMILY_IPV4 4
|
||||
# define BIO_FAMILY_IPV6 6
|
||||
# define BIO_FAMILY_IPANY 256
|
||||
|
||||
# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
|
||||
/* BIO_s_connect() */
|
||||
# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
|
||||
# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
|
||||
# define BIO_set_conn_address(b,addr) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)addr)
|
||||
# define BIO_set_conn_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f)
|
||||
# define BIO_get_conn_hostname(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0,NULL))
|
||||
# define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1,NULL))
|
||||
# define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2,NULL))
|
||||
# define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL)
|
||||
# define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL)
|
||||
|
||||
# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
|
||||
|
||||
/* BIO_s_accept() */
|
||||
# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
|
||||
# define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
|
||||
# define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
|
||||
# define BIO_set_accept_port(b,port) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(char *)port)
|
||||
# define BIO_get_accept_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0))
|
||||
# define BIO_get_accept_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,1))
|
||||
# define BIO_get_peer_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,2))
|
||||
# define BIO_get_peer_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,3))
|
||||
/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
|
||||
# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
|
||||
# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
|
||||
# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(n)?(void *)"a":NULL)
|
||||
# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,3,(char *)bio)
|
||||
# define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f)
|
||||
# define BIO_get_accept_ip_family(b) BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL)
|
||||
|
||||
/* Aliases kept for backward compatibility */
|
||||
# define BIO_BIND_NORMAL 0
|
||||
# define BIO_BIND_REUSEADDR_IF_UNUSED 1
|
||||
# define BIO_BIND_REUSEADDR 2
|
||||
# define BIO_BIND_REUSEADDR BIO_SOCK_REUSEADDR
|
||||
# define BIO_BIND_REUSEADDR_IF_UNUSED BIO_SOCK_REUSEADDR
|
||||
# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
|
||||
# define BIO_get_bind_mode(b) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
|
||||
|
||||
@ -637,7 +644,7 @@ long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
|
||||
long BIO_callback_ctrl(BIO *b, int cmd,
|
||||
void (*fp) (struct bio_st *, int, const char *, int,
|
||||
long, long));
|
||||
char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
|
||||
void *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
|
||||
long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
|
||||
BIO *BIO_push(BIO *b, BIO *append);
|
||||
BIO *BIO_pop(BIO *b);
|
||||
@ -763,9 +770,6 @@ int BIO_socket(int domain, int socktype, int protocol, int options);
|
||||
int BIO_connect(int sock, const BIO_ADDR *addr, int options);
|
||||
int BIO_listen(int sock, const BIO_ADDR *addr, int options);
|
||||
int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options);
|
||||
# if OPENSSL_API_COMPAT >= 0x10100000L
|
||||
# define BIO_accept(as,s,a) BIO_accept_ex((as),(s),(a))
|
||||
# endif
|
||||
int BIO_closesocket(int sock);
|
||||
|
||||
BIO *BIO_new_socket(int sock, int close_flag);
|
||||
@ -895,7 +899,7 @@ void ERR_load_BIO_strings(void);
|
||||
# define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111
|
||||
# define BIO_R_NO_HOSTNAME_SPECIFIED 112
|
||||
# define BIO_R_NO_PORT_DEFINED 113
|
||||
# define BIO_R_NO_PORT_SPECIFIED 114
|
||||
# define BIO_R_NO_SERVICE_SPECIFIED 114
|
||||
# define BIO_R_NO_SUCH_FILE 128
|
||||
# define BIO_R_NULL_PARAMETER 115
|
||||
# define BIO_R_TAG_MISMATCH 116
|
||||
|
Loading…
Reference in New Issue
Block a user