提交 417be660 编写于 作者: R Richard Levitte

Refactoring BIO: adapt BIO_s_connect and BIO_s_accept

Reviewed-by: NKurt Roeckx <kurt@openssl.org>
上级 4f1374e6
...@@ -325,9 +325,9 @@ long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) ...@@ -325,9 +325,9 @@ long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
return (BIO_ctrl(b, cmd, larg, (char *)&i)); 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) if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
return (NULL); return (NULL);
......
...@@ -57,36 +57,27 @@ ...@@ -57,36 +57,27 @@
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#define USE_SOCKETS #include "bio_lcl.h"
#include "internal/cryptlib.h"
#include <openssl/bio.h>
#ifndef OPENSSL_NO_SOCK #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 { typedef struct bio_accept_st {
int state; 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_addr;
char *param_serv;
int accept_sock; int accept_sock;
int accept_nbio;
char *addr; BIO_ADDRINFO *addr_first;
int nbio; const BIO_ADDRINFO *addr_iter;
/* BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */
* If 0, it means normal, if 1, do a connect on bind failure, and if char *cache_accepting_name, *cache_accepting_serv;
* there is no-one listening, bind with SO_REUSEADDR. If 2, always use BIO_ADDR cache_peer_addr;
* SO_REUSEADDR. char *cache_peer_name, *cache_peer_serv;
*/
int bind_mode;
BIO *bio_chain; BIO *bio_chain;
} BIO_ACCEPT; } BIO_ACCEPT;
...@@ -102,8 +93,11 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void); ...@@ -102,8 +93,11 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void);
static void BIO_ACCEPT_free(BIO_ACCEPT *a); static void BIO_ACCEPT_free(BIO_ACCEPT *a);
# define ACPT_S_BEFORE 1 # define ACPT_S_BEFORE 1
# define ACPT_S_GET_ACCEPT_SOCKET 2 # define ACPT_S_GET_ADDR 2
# define ACPT_S_OK 3 # 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 = { static BIO_METHOD methods_acceptp = {
BIO_TYPE_ACCEPT, BIO_TYPE_ACCEPT,
...@@ -144,8 +138,8 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void) ...@@ -144,8 +138,8 @@ static BIO_ACCEPT *BIO_ACCEPT_new(void)
if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
return (NULL); return (NULL);
ret->accept_family = BIO_FAMILY_IPANY;
ret->accept_sock = (int)INVALID_SOCKET; ret->accept_sock = (int)INVALID_SOCKET;
ret->bind_mode = BIO_BIND_NORMAL;
return (ret); return (ret);
} }
...@@ -155,7 +149,12 @@ static void BIO_ACCEPT_free(BIO_ACCEPT *a) ...@@ -155,7 +149,12 @@ static void BIO_ACCEPT_free(BIO_ACCEPT *a)
return; return;
OPENSSL_free(a->param_addr); 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); BIO_free(a->bio_chain);
OPENSSL_free(a); OPENSSL_free(a);
} }
...@@ -194,102 +193,203 @@ static int acpt_free(BIO *a) ...@@ -194,102 +193,203 @@ static int acpt_free(BIO *a)
static int acpt_state(BIO *b, BIO_ACCEPT *c) static int acpt_state(BIO *b, BIO_ACCEPT *c)
{ {
BIO *bio = NULL, *dbio; BIO *bio = NULL, *dbio;
int s = -1; int s = -1, ret = -1;
int i;
for (;;) {
again: switch (c->state) {
switch (c->state) { case ACPT_S_BEFORE:
case ACPT_S_BEFORE: if (c->param_addr == NULL && c->param_serv == NULL) {
if (c->param_addr == NULL) { BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED);
BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED); ERR_add_error_data(4,
return (-1); "hostname=", c->param_addr,
} " service=", c->param_serv);
s = BIO_get_accept_socket(c->param_addr, c->bind_mode); goto exit_loop;
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);
} }
}
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) {
c->state = ACPT_S_OK;
goto again;
}
BIO_clear_retry_flags(b);
b->retry_reason = 0;
i = BIO_accept(c->accept_sock, &(c->addr));
/* -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) /* Because we're starting a new bind, any cached name and serv
return (i); * 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;
}
}
bio = BIO_new_socket(i, BIO_CLOSE); {
if (bio == NULL) union BIO_sock_info_u info;
goto err;
BIO_set_callback(bio, BIO_get_callback(b)); info.addr = &c->cache_accepting_addr;
BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS,
&info)) {
BIO_closesocket(c->accept_sock);
goto exit_loop;
}
}
if (c->nbio) { c->cache_accepting_name =
if (!BIO_socket_nbio(i, 1)) { BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
BIOerr(BIO_F_ACPT_STATE, c->cache_accepting_serv =
BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET); BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
goto err; 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 the accept BIO has an bio_chain, we dup it and put the new if (s < 0) {
* socket at the end. ret = s;
*/ goto exit_loop;
if (c->bio_chain != NULL) { }
if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
goto err; bio = BIO_new_socket(s, BIO_CLOSE);
if (!BIO_push(dbio, bio)) if (bio == NULL)
goto err; goto exit_loop;
bio = dbio;
} BIO_set_callback(bio, BIO_get_callback(b));
if (BIO_push(b, bio) == NULL) BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
goto err;
/*
c->state = ACPT_S_OK; * If the accept BIO has an bio_chain, we dup it and put the new
return (1); * socket at the end.
err: */
if (bio != NULL) if (c->bio_chain != NULL) {
BIO_free(bio); if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
else if (s >= 0) goto exit_loop;
closesocket(s); if (!BIO_push(dbio, bio))
return (0); goto exit_loop;
/* break; */ bio = dbio;
case ACPT_S_OK: }
if (b->next_bio == NULL) { if (BIO_push(b, bio) == NULL)
c->state = ACPT_S_GET_ACCEPT_SOCKET; goto exit_loop;
goto again;
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;
bio = NULL;
ret = 1;
goto end;
case ACPT_S_OK:
if (b->next_bio == NULL) {
c->state = ACPT_S_ACCEPT;
break;
}
ret = 1;
goto end;
default:
ret = 0;
goto end;
} }
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) 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) ...@@ -344,6 +444,8 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0; ret = 0;
data->state = ACPT_S_BEFORE; data->state = ACPT_S_BEFORE;
acpt_close_socket(b); acpt_close_socket(b);
BIO_ADDRINFO_free(data->addr_first);
data->addr_first = NULL;
b->flags = 0; b->flags = 0;
break; break;
case BIO_C_DO_STATE_MACHINE: case BIO_C_DO_STATE_MACHINE:
...@@ -353,25 +455,48 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -353,25 +455,48 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_C_SET_ACCEPT: case BIO_C_SET_ACCEPT:
if (ptr != NULL) { if (ptr != NULL) {
if (num == 0) { 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); 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) { } 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) { } 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); BIO_free(data->bio_chain);
data->bio_chain = (BIO *)ptr; data->bio_chain = (BIO *)ptr;
} else if (num == 4) {
data->accept_family = *(int *)ptr;
} }
} }
break; break;
case BIO_C_SET_NBIO: 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; break;
case BIO_C_SET_FD: case BIO_C_SET_FD:
b->init = 1; b->init = 1;
b->num = *((int *)ptr); b->num = *((int *)ptr);
data->accept_sock = b->num; data->accept_sock = b->num;
data->state = ACPT_S_GET_ACCEPT_SOCKET; data->state = ACPT_S_ACCEPT;
b->shutdown = (int)num; b->shutdown = (int)num;
b->init = 1; b->init = 1;
break; break;
...@@ -386,9 +511,35 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -386,9 +511,35 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
break; break;
case BIO_C_GET_ACCEPT: case BIO_C_GET_ACCEPT:
if (b->init) { if (b->init) {
if (ptr != NULL) { if (num == 0 && ptr != NULL) {
pp = (char **)ptr; 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 } else
ret = -1; ret = -1;
} else } else
......
...@@ -57,31 +57,20 @@ ...@@ -57,31 +57,20 @@
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#define USE_SOCKETS
#include "internal/cryptlib.h"
#include <openssl/bio.h>
#ifndef OPENSSL_NO_SOCK #include "bio_lcl.h"
/*
* 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) #ifndef OPENSSL_NO_SOCK
/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
# undef FIONBIO
# endif
typedef struct bio_connect_st { typedef struct bio_connect_st {
int state; int state;
int connect_family;
char *param_hostname; char *param_hostname;
char *param_port; char *param_service;
int nbio; int connect_mode;
unsigned char ip[4];
unsigned short port; BIO_ADDRINFO *addr_first;
struct sockaddr_in them; const BIO_ADDRINFO *addr_iter;
/* /*
* int socket; this will be kept in bio->num so that it is compatible * int socket; this will be kept in bio->num so that it is compatible
* with the bss_sock bio * with the bss_sock bio
...@@ -107,6 +96,13 @@ static void conn_close_socket(BIO *data); ...@@ -107,6 +96,13 @@ static void conn_close_socket(BIO *data);
BIO_CONNECT *BIO_CONNECT_new(void); BIO_CONNECT *BIO_CONNECT_new(void);
void BIO_CONNECT_free(BIO_CONNECT *a); 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 = { static BIO_METHOD methods_connectp = {
BIO_TYPE_CONNECT, BIO_TYPE_CONNECT,
"socket connect", "socket connect",
...@@ -123,8 +119,6 @@ static BIO_METHOD methods_connectp = { ...@@ -123,8 +119,6 @@ static BIO_METHOD methods_connectp = {
static int conn_state(BIO *b, BIO_CONNECT *c) static int conn_state(BIO *b, BIO_CONNECT *c)
{ {
int ret = -1, i; int ret = -1, i;
unsigned long l;
char *p, *q;
int (*cb) (const BIO *, int, int) = NULL; int (*cb) (const BIO *, int, int) = NULL;
if (c->info_callback != NULL) if (c->info_callback != NULL)
...@@ -133,122 +127,103 @@ static int conn_state(BIO *b, BIO_CONNECT *c) ...@@ -133,122 +127,103 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
for (;;) { for (;;) {
switch (c->state) { switch (c->state) {
case BIO_CONN_S_BEFORE: case BIO_CONN_S_BEFORE:
p = c->param_hostname; if (c->param_hostname == NULL && c->param_service == NULL) {
if (p == NULL) { BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_SPECIFIED); ERR_add_error_data(4,
"hostname=", c->param_hostname,
" service=", c->param_service);
goto exit_loop; goto exit_loop;
} }
for (; *p != '\0'; p++) { c->state = BIO_CONN_S_GET_ADDR;
if ((*p == ':') || (*p == '/')) break;
break;
}
i = *p; case BIO_CONN_S_GET_ADDR:
if ((i == ':') || (i == '/')) { {
int family = AF_UNSPEC;
*(p++) = '\0'; switch (c->connect_family) {
if (i == ':') { case BIO_FAMILY_IPV6:
for (q = p; *q; q++) if (1) { /* This is a trick we use to avoid bit rot.
if (*q == '/') { * at least the "else" part will always be
*q = '\0'; * compiled.
break; */
} #ifdef AF_INET6
OPENSSL_free(c->param_port); family = AF_INET6;
c->param_port = OPENSSL_strdup(p); } else {
#endif
BIOerr(BIO_F_CONN_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_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->addr_first == NULL) {
if (c->param_port == NULL) { BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
BIOerr(BIO_F_CONN_STATE, BIO_R_NO_PORT_SPECIFIED);
ERR_add_error_data(2, "host=", c->param_hostname);
goto exit_loop; goto exit_loop;
} }
c->state = BIO_CONN_S_GET_IP; c->addr_iter = c->addr_first;
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->state = BIO_CONN_S_CREATE_SOCKET; c->state = BIO_CONN_S_CREATE_SOCKET;
break; break;
case BIO_CONN_S_CREATE_SOCKET: case BIO_CONN_S_CREATE_SOCKET:
/* now setup address */ ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
memset(&c->them, 0, sizeof(c->them)); BIO_ADDRINFO_socktype(c->addr_iter),
c->them.sin_family = AF_INET; BIO_ADDRINFO_protocol(c->addr_iter), 0);
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);
if (ret == (int)INVALID_SOCKET) { if (ret == (int)INVALID_SOCKET) {
SYSerr(SYS_F_SOCKET, get_last_socket_error()); SYSerr(SYS_F_SOCKET, get_last_socket_error());
ERR_add_error_data(4, "host=", c->param_hostname, ERR_add_error_data(4,
":", c->param_port); "hostname=", c->param_hostname,
" service=", c->param_service);
BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
goto exit_loop; goto exit_loop;
} }
b->num = ret; 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; 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; break;
case BIO_CONN_S_CONNECT: case BIO_CONN_S_CONNECT:
BIO_clear_retry_flags(b); BIO_clear_retry_flags(b);
ret = connect(b->num, ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
(struct sockaddr *)&c->them, sizeof(c->them)); BIO_SOCK_KEEPALIVE | c->connect_mode);
b->retry_reason = 0; b->retry_reason = 0;
if (ret < 0) { if (ret < 0) {
if (BIO_sock_should_retry(ret)) { if (BIO_sock_should_retry(ret)) {
BIO_set_retry_special(b); BIO_set_retry_special(b);
c->state = BIO_CONN_S_BLOCKED_CONNECT; c->state = BIO_CONN_S_BLOCKED_CONNECT;
b->retry_reason = BIO_RR_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 { } else {
SYSerr(SYS_F_CONNECT, get_last_socket_error()); SYSerr(SYS_F_CONNECT, get_last_socket_error());
ERR_add_error_data(4, "host=", ERR_add_error_data(4,
c->param_hostname, ":", c->param_port); "hostname=", c->param_hostname,
" service=", c->param_service);
BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
} }
goto exit_loop; goto exit_loop;
} else } else {
c->state = BIO_CONN_S_OK; c->state = BIO_CONN_S_OK;
}
break; break;
case BIO_CONN_S_BLOCKED_CONNECT: case BIO_CONN_S_BLOCKED_CONNECT:
...@@ -256,8 +231,9 @@ static int conn_state(BIO *b, BIO_CONNECT *c) ...@@ -256,8 +231,9 @@ static int conn_state(BIO *b, BIO_CONNECT *c)
if (i) { if (i) {
BIO_clear_retry_flags(b); BIO_clear_retry_flags(b);
SYSerr(SYS_F_CONNECT, i); SYSerr(SYS_F_CONNECT, i);
ERR_add_error_data(4, "host=", ERR_add_error_data(4,
c->param_hostname, ":", c->param_port); "hostname=", c->param_hostname,
" service=", c->param_service);
BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR); BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
ret = 0; ret = 0;
goto exit_loop; goto exit_loop;
...@@ -294,9 +270,13 @@ BIO_CONNECT *BIO_CONNECT_new(void) ...@@ -294,9 +270,13 @@ BIO_CONNECT *BIO_CONNECT_new(void)
if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
return (NULL); return (NULL);
ret->state = BIO_CONN_S_BEFORE; ret->state = BIO_CONN_S_BEFORE;
ret->connect_family = BIO_FAMILY_IPANY;
ret->param_hostname = NULL; ret->param_hostname = NULL;
ret->param_port = NULL; ret->param_service = NULL;
ret->info_callback = NULL; ret->info_callback = NULL;
ret->connect_mode = 0;
ret->addr_first = NULL;
ret->addr_iter = NULL;
return (ret); return (ret);
} }
...@@ -306,7 +286,8 @@ void BIO_CONNECT_free(BIO_CONNECT *a) ...@@ -306,7 +286,8 @@ void BIO_CONNECT_free(BIO_CONNECT *a)
return; return;
OPENSSL_free(a->param_hostname); OPENSSL_free(a->param_hostname);
OPENSSL_free(a->param_port); OPENSSL_free(a->param_service);
BIO_ADDRINFO_free(a->addr_first);
OPENSSL_free(a); OPENSSL_free(a);
} }
...@@ -335,7 +316,7 @@ static void conn_close_socket(BIO *bio) ...@@ -335,7 +316,7 @@ static void conn_close_socket(BIO *bio)
/* Only do a shutdown if things were established */ /* Only do a shutdown if things were established */
if (c->state == BIO_CONN_S_OK) if (c->state == BIO_CONN_S_OK)
shutdown(bio->num, 2); shutdown(bio->num, 2);
closesocket(bio->num); BIO_closesocket(bio->num);
bio->num = (int)INVALID_SOCKET; bio->num = (int)INVALID_SOCKET;
} }
} }
...@@ -419,6 +400,8 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -419,6 +400,8 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0; ret = 0;
data->state = BIO_CONN_S_BEFORE; data->state = BIO_CONN_S_BEFORE;
conn_close_socket(b); conn_close_socket(b);
BIO_ADDRINFO_free(data->addr_first);
data->addr_first = NULL;
b->flags = 0; b->flags = 0;
break; break;
case BIO_C_DO_STATE_MACHINE: case BIO_C_DO_STATE_MACHINE:
...@@ -431,27 +414,33 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -431,27 +414,33 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_C_GET_CONNECT: case BIO_C_GET_CONNECT:
if (ptr != NULL) { if (ptr != NULL) {
pptr = (const char **)ptr; pptr = (const char **)ptr;
} if (num == 0) {
*pptr = data->param_hostname;
if (b->init) { } else if (num == 1) {
if (pptr != NULL) { *pptr = data->param_service;
ret = 1; } else if (num == 2) {
if (num == 0) { *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
*pptr = data->param_hostname; } else if (num == 3) {
} else if (num == 1) { switch (BIO_ADDRINFO_family(data->addr_iter)) {
*pptr = data->param_port; # ifdef AF_INET6
} else if (num == 2) { case AF_INET6:
*pptr = (char *)&(data->ip[0]); ret = BIO_FAMILY_IPV6;
} else { break;
ret = 0; # endif
case AF_INET:
ret = BIO_FAMILY_IPV4;
break;
case 0:
ret = data->connect_family;
break;
default:
ret = -1;
break;
} }
} } else {
if (num == 3) { ret = 0;
ret = data->port;
} }
} else { } else {
if (pptr != NULL)
*pptr = "not initialized";
ret = 0; ret = 0;
} }
break; break;
...@@ -459,32 +448,46 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -459,32 +448,46 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
if (ptr != NULL) { if (ptr != NULL) {
b->init = 1; b->init = 1;
if (num == 0) { 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); 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) { } else if (num == 1) {
OPENSSL_free(data->param_port); OPENSSL_free(data->param_service);
data->param_port = OPENSSL_strdup(ptr); data->param_service = BUF_strdup(ptr);
} else if (num == 2) { } else if (num == 2) {
char buf[16]; const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
unsigned char *p = ptr; if (ret) {
data->param_hostname = BIO_ADDR_hostname_string(addr, 1);
BIO_snprintf(buf, sizeof buf, "%d.%d.%d.%d", data->param_service = BIO_ADDR_service_string(addr, 1);
p[0], p[1], p[2], p[3]); BIO_ADDRINFO_free(data->addr_first);
OPENSSL_free(data->param_hostname); data->addr_first = NULL;
data->param_hostname = OPENSSL_strdup(buf); data->addr_iter = NULL;
memcpy(&(data->ip[0]), ptr, 4); }
} else if (num == 3) { } else if (num == 3) {
char buf[DECIMAL_SIZE(int) + 1]; data->connect_family = *(int *)ptr;
} else {
BIO_snprintf(buf, sizeof buf, "%d", *(int *)ptr); ret = 0;
OPENSSL_free(data->param_port);
data->param_port = OPENSSL_strdup(buf);
data->port = *(int *)ptr;
} }
} }
break; break;
case BIO_C_SET_NBIO: 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; break;
case BIO_C_GET_FD: case BIO_C_GET_FD:
if (b->init) { if (b->init) {
...@@ -510,11 +513,12 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) ...@@ -510,11 +513,12 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_DUP: case BIO_CTRL_DUP:
{ {
dbio = (BIO *)ptr; dbio = (BIO *)ptr;
if (data->param_port)
BIO_set_conn_port(dbio, data->param_port);
if (data->param_hostname) if (data->param_hostname)
BIO_set_conn_hostname(dbio, 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 * FIXME: the cast of the function seems unlikely to be a good
* idea * idea
......
...@@ -169,7 +169,8 @@ unencrypted example in L<BIO_s_connect(3)>. ...@@ -169,7 +169,8 @@ unencrypted example in L<BIO_s_connect(3)>.
/* We might want to do other things with ssl here */ /* 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); out = BIO_new_fp(stdout, BIO_NOCLOSE);
if(BIO_do_connect(sbio) <= 0) { if(BIO_do_connect(sbio) <= 0) {
......
...@@ -59,11 +59,12 @@ the accept socket. See L<BIO_s_fd(3)> ...@@ -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 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", 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. where "host" is the interface to use and "port" is the port.
The host can be "*" which is interpreted as meaning The host can be "*" or empty which is interpreted as meaning
any interface; "port" has the same syntax any interface. If the host is a IPv6 address, it has to be
as the port specified in BIO_set_conn_port() for connect BIOs, enclosed in brackets, for example "[::1]:https". "port" has the
that is it can be a numerical port string or a string to lookup same syntax as the port specified in BIO_set_conn_port() for
using getservbyname() and a string table. 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 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 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 ...@@ -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_hostname(BIO *b, char *name);
long BIO_set_conn_port(BIO *b, char *port); long BIO_set_conn_port(BIO *b, char *port);
long BIO_set_conn_ip(BIO *b, char *ip); long BIO_set_conn_address(BIO *b, BIO_ADDR *addr);
long BIO_set_conn_int_port(BIO *b, char *port); const char *BIO_get_conn_hostname(BIO *b);
char *BIO_get_conn_hostname(BIO *b); const char *BIO_get_conn_port(BIO *b);
char *BIO_get_conn_port(BIO *b); const BIO_ADDR *BIO_get_conn_address(BIO *b);
char *BIO_get_conn_ip(BIO *b);
long BIO_get_conn_int_port(BIO *b);
long BIO_set_nbio(BIO *b, long n); 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 ...@@ -57,9 +55,9 @@ it also returns the socket . If B<c> is not NULL it should be of
type (int *). type (int *).
BIO_set_conn_hostname() uses the string B<name> to set the hostname. 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 The hostname can be an IP address; if the address is a IPv6 one, it
port in the form hostname:port . It is also acceptable to use the must be enclosed with brackets. The hostname can also include the
form "hostname/any/other/path" or "hostname:port/any/other/path". port in the form hostname:port.
BIO_set_conn_port() sets the port to B<port>. B<port> can be the 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 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 ...@@ -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 fails a standard table of port names will be used. This internal
list is http, telnet, socks, https, ssl, ftp, and gopher. list is http, telnet, socks, https, ssl, ftp, and gopher.
BIO_set_conn_ip() sets the IP address to B<ip> using binary form, BIO_set_conn_address() sets the address and port information using
that is four bytes specifying the IP address in big-endian form. a BIO_ADDR(3ssl).
BIO_set_conn_int_port() sets the port using B<port>. B<port> should
be of type (int *).
BIO_get_conn_hostname() returns the hostname of the connect BIO or BIO_get_conn_hostname() returns the hostname of the connect BIO or
NULL if the BIO is initialized but no hostname is set. NULL if the BIO is initialized but no hostname is set.
This return value is an internal pointer which should not be modified. This return value is an internal pointer which should not be modified.
BIO_get_conn_port() returns the port as a string. 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_address() returns the address information as a BIO_ADDR.
This return value is an internal pointer which should not be modified.
BIO_get_conn_int_port() returns the port as an int.
BIO_set_nbio() sets the non blocking I/O flag to B<n>. If B<n> is 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 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. ...@@ -189,4 +184,4 @@ to retrieve a page and copy the result to standard output.
=head1 SEE ALSO =head1 SEE ALSO
TBA L<BIO_ADDR(3)>
...@@ -382,15 +382,6 @@ struct bio_dgram_sctp_prinfo { ...@@ -382,15 +382,6 @@ struct bio_dgram_sctp_prinfo {
}; };
# endif # 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 * #define BIO_CONN_get_param_hostname BIO_ctrl
*/ */
...@@ -455,31 +446,47 @@ struct bio_dgram_sctp_prinfo { ...@@ -455,31 +446,47 @@ struct bio_dgram_sctp_prinfo {
# define BIO_C_SET_EX_ARG 153 # define BIO_C_SET_EX_ARG 153
# define BIO_C_GET_EX_ARG 154 # 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_set_app_data(s,arg) BIO_set_ex_data(s,0,arg)
# define BIO_get_app_data(s) BIO_get_ex_data(s,0) # define BIO_get_app_data(s) BIO_get_ex_data(s,0)
/* BIO_s_connect() and BIO_s_socks4a_connect() */ /* 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
/* BIO_s_connect() */
# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) # 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_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_address(b,addr) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)addr)
# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) # define BIO_set_conn_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f)
# define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) # define BIO_get_conn_hostname(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0,NULL))
# define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) # define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1,NULL))
# define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) # define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2,NULL))
# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,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) # define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
/* BIO_s_accept() */ /* BIO_s_accept() */
# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) # define BIO_set_accept_name(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_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(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_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,2,(char *)bio) # 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_NORMAL 0
# define BIO_BIND_REUSEADDR_IF_UNUSED 1 # define BIO_BIND_REUSEADDR BIO_SOCK_REUSEADDR
# define BIO_BIND_REUSEADDR 2 # 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_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) # 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); ...@@ -637,7 +644,7 @@ long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
long BIO_callback_ctrl(BIO *b, int cmd, long BIO_callback_ctrl(BIO *b, int cmd,
void (*fp) (struct bio_st *, int, const char *, int, void (*fp) (struct bio_st *, int, const char *, int,
long, long)); 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); long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
BIO *BIO_push(BIO *b, BIO *append); BIO *BIO_push(BIO *b, BIO *append);
BIO *BIO_pop(BIO *b); BIO *BIO_pop(BIO *b);
...@@ -763,9 +770,6 @@ int BIO_socket(int domain, int socktype, int protocol, int options); ...@@ -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_connect(int sock, const BIO_ADDR *addr, int options);
int BIO_listen(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); 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); int BIO_closesocket(int sock);
BIO *BIO_new_socket(int sock, int close_flag); BIO *BIO_new_socket(int sock, int close_flag);
...@@ -895,7 +899,7 @@ void ERR_load_BIO_strings(void); ...@@ -895,7 +899,7 @@ void ERR_load_BIO_strings(void);
# define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 # define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111
# define BIO_R_NO_HOSTNAME_SPECIFIED 112 # define BIO_R_NO_HOSTNAME_SPECIFIED 112
# define BIO_R_NO_PORT_DEFINED 113 # 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_NO_SUCH_FILE 128
# define BIO_R_NULL_PARAMETER 115 # define BIO_R_NULL_PARAMETER 115
# define BIO_R_TAG_MISMATCH 116 # define BIO_R_TAG_MISMATCH 116
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册